Example #1
0
 def _test_file( self, testFile_basename, solution = None ):
     testFile = os.path.join( test_assembly_path, testFile_basename + '.fcstd' )
     debugPrint(1, testFile_basename )
     stats.n_attempted += 1
     #if testFile == 'tests/testAssembly11-Pipe_assembly.fcstd':
     #    print('Skipping known fail')
     #    continue
     doc =  FreeCAD.open(testFile)
     t_start_solver = time.time()
     constraintSystem = solveConstraints( doc, solver_name = 'dof_reduction_solver', use_cache = self.use_cache )
     if solution:
         self.check_solution( constraintSystem, solution )
     stats.t_solver += time.time() - t_start_solver
     if  self.use_cache:
         debugPrint(1,'\n\n')
         X_org = constraintSystem.variableManager.X
         t_start_cache = time.time()
         #cache.debugMode = 1
         constraintSystem = solveConstraints( doc, solver_name = 'dof_reduction_solver', use_cache =  self.use_cache )
         self.assertTrue(
             numpy.allclose( X_org , constraintSystem.variableManager.X ),
             'Cache solution differs from originial solution: %s != %s' % ( X_org , constraintSystem.variableManager.X )
         )
         #cache.debugMode = 0
         stats.t_cache += time.time() - t_start_cache
         constraintSystem.update()
     stats.n_solved += 1
     debugPrint(1,'\n\n\n')
Example #2
0
 def _test_file( self, testFile_basename, solution = None ):
     testFile = os.path.join( test_assembly_path, testFile_basename + '.fcstd' )
     debugPrint(1, testFile_basename )
     stats.n_attempted += 1
     #if testFile == 'tests/testAssembly11-Pipe_assembly.fcstd':
     #    print('Skipping known fail')
     #    continue
     doc =  FreeCAD.open(testFile)
     t_start_solver = time.time()
     constraintSystem = solveConstraints( doc, solver_name = 'dof_reduction_solver', use_cache = self.use_cache, showFailureErrorDialog=False )
     if solution:
         self.check_solution( constraintSystem, solution )
     stats.t_solver += time.time() - t_start_solver
     if  self.use_cache:
         debugPrint(1,'\n\n')
         X_org = constraintSystem.variableManager.X
         t_start_cache = time.time()
         #cache.debugMode = 1
         constraintSystem = solveConstraints( doc, solver_name = 'dof_reduction_solver', use_cache =  self.use_cache )
         self.assertTrue(
             numpy.allclose( X_org , constraintSystem.variableManager.X ),
             'Cache solution differs from originial solution: %s != %s' % ( X_org , constraintSystem.variableManager.X )
         )
         #cache.debugMode = 0
         stats.t_cache += time.time() - t_start_cache
         constraintSystem.update()
     stats.n_solved += 1
     FreeCAD.closeDocument( doc.Name )
     debugPrint(1,'\n\n\n')
Example #3
0
def boltSelection():
    from assembly2.solvers import solveConstraints
    doc = FreeCAD.ActiveDocument
    doc.openTransaction('Bolt Multiple Circular Edges')
    selection = FreeCADGui.Selection.getSelectionEx()
    bolt = selection[0].Object
    bolt_se_name = selection[0].SubElementNames[0]
    S = []  #edgesToConstrainTo
    for s in selection[1:]:
        for se_name in s.SubElementNames:
            S.append(SelectionExObject(doc, s.Object, se_name))
    for s2 in S:
        newBolt = duplicateImportedPart(bolt)
        s1 = SelectionExObject(doc, newBolt, bolt_se_name)
        debugPrint(3, 's1 %s' % [s1, s2])
        parseSelection([s1, s2], callSolveConstraints=False, lockRotation=True)
    solveConstraints(doc)
    FreeCAD.ActiveDocument.commitTransaction()
    repair_tree_view()
def boltSelection():
    from assembly2.solvers import solveConstraints
    doc = FreeCAD.ActiveDocument
    doc.openTransaction('Bolt Multiple Circular Edges')
    selection = FreeCADGui.Selection.getSelectionEx()
    bolt = selection[0].Object
    bolt_se_name = selection[0].SubElementNames[0]
    S = [] #edgesToConstrainTo
    for s in selection[1:]:
        for se_name in s.SubElementNames:
            S.append( SelectionExObject(doc, s.Object, se_name) )
    for s2 in S:
        newBolt = duplicateImportedPart(bolt)
        s1 = SelectionExObject(doc, newBolt, bolt_se_name)
        debugPrint(3,'s1 %s' % [s1, s2])
        parseSelection(
            [s1, s2 ],
            callSolveConstraints= False, lockRotation = True
            )
    solveConstraints( doc )
    FreeCAD.ActiveDocument.commitTransaction()
    repair_tree_view()
Example #5
0
 def _test_file( self, testFile_basename, solution = None ):
     testFile = os.path.join( test_assembly_path, testFile_basename + '.fcstd' )
     debugPrint(1, testFile_basename )
     stats.n_attempted += 1
     #if testFile == 'tests/testAssembly11-Pipe_assembly.fcstd':
     #    print('Skipping known fail')
     #    continue
     doc =  FreeCAD.open(testFile)
     t_start_solver = time.time()
     xOpt = solveConstraints( doc, solver_name = 'newton_solver_slsqp', use_cache = self.use_cache, showFailureErrorDialog=False )
     if solution:
         self.check_solution( xOpt, solution )
     stats.t_solver += time.time() - t_start_solver
     assert not self.use_cache
     if not xOpt is None:
         stats.n_solved += 1
     FreeCAD.closeDocument( doc.Name )
     debugPrint(1,'\n\n\n')
     return xOpt
Example #6
0
    def Activated(self):
        #disable proxies solving the system as their objects are updated
        doc_assembly = FreeCAD.ActiveDocument
        solve_assembly_constraints = False
        YesToAll_clicked = False
        for obj in doc_assembly.Objects:
            if hasattr(obj, 'sourceFile'):
                if not hasattr( obj, 'timeLastImport'):
                    obj.addProperty("App::PropertyFloat", "timeLastImport","importPart") #should default to zero which will force update.
                    obj.setEditorMode("timeLastImport",1)
                if not os.path.exists( obj.sourceFile ) and  path_rel_to_abs( obj.sourceFile ) is None:
                    debugPrint( 3, '%s.sourceFile %s is missing, attempting to repair it' % (obj.Name,  obj.sourceFile) )
                    replacement = None
                    aFolder, aFilename = posixpath.split( doc_assembly.FileName )
                    sParts = path_split( posixpath, obj.sourceFile)
                    debugPrint( 3, '  obj.sourceFile parts %s' % sParts )
                    replacement = None
                    previousRejects = []
                    while replacement == None and aFilename != '':
                        for i in reversed(range(len(sParts))):
                            newFn = aFolder
                            for j in range(i,len(sParts)):
                                newFn = posixpath.join( newFn,sParts[j] )
                            debugPrint( 4, '    checking %s' % newFn )
                            if os.path.exists( newFn ) and not newFn in previousRejects :
                                if YesToAll_clicked:
                                    replacement = newFn
                                    break
                                reply = QtGui.QMessageBox.question(
                                    QtGui.QApplication.activeWindow(), "%s source file not found" % obj.Name,
                                    "Unable to find\n  %s \nUse \n  %s\n instead?" % (obj.sourceFile, newFn) ,
                                    QtGui.QMessageBox.Yes | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)
                                if reply == QtGui.QMessageBox.Yes:
                                    replacement = newFn
                                    break
                                if reply == QtGui.QMessageBox.YesToAll:
                                    replacement = newFn
                                    YesToAll_clicked = True
                                    break
                                else:
                                    previousRejects.append( newFn )
                        aFolder, aFilename = posixpath.split( aFolder )
                    if replacement != None:
                        obj.sourceFile = replacement
                    else:
                        QtGui.QMessageBox.critical(  QtGui.QApplication.activeWindow(), "Source file not found", "update of %s aborted!\nUnable to find %s" % (obj.Name, obj.sourceFile) )
                        obj.timeLastImport = 0 #force update if users repairs link
                if path_rel_to_abs( obj.sourceFile ) is not None:
                    absolutePath = path_rel_to_abs( obj.sourceFile )
                    if os.path.getmtime( absolutePath ) > obj.timeLastImport:
                        importPart( absolutePath, obj.Name,  doc_assembly )
                        solve_assembly_constraints = True
                if os.path.exists( obj.sourceFile ):
                    if os.path.getmtime( obj.sourceFile ) > obj.timeLastImport:
                        importPart( obj.sourceFile, obj.Name,  doc_assembly )
                        solve_assembly_constraints = True

        if solve_assembly_constraints:
            solveConstraints( doc_assembly )
        # constraint mirror house keeping

        for obj in doc_assembly.Objects: #for adding creating mirrored constraints in old files
            if 'ConstraintInfo' in obj.Content:
                if doc_assembly.getObject( obj.Object1 ) == None or doc_assembly.getObject( obj.Object2 ) == None:
                    debugPrint(2, 'removing %s which refers to non-existent objects' % obj.Name)
                    doc_assembly.removeObject( obj.Name ) #required for FreeCAD 0.15 which does not support the on-delete method
                if group_constraints_under_parts():
                    if not hasattr( obj.ViewObject.Proxy, 'mirror_name'):
                        if isinstance( doc_assembly.getObject( obj.Object1 ).Proxy, Proxy_importPart) \
                                or isinstance( doc_assembly.getObject( obj.Object2 ).Proxy, Proxy_importPart):
                            debugPrint(2, 'creating mirror of %s' % obj.Name)
                            doc_assembly.getObject( obj.Object2 ).touch()
                            obj.ViewObject.Proxy.mirror_name = create_constraint_mirror(  obj, obj.ViewObject.Proxy.iconPath )
            elif 'ConstraintNfo' in obj.Content: #constraint mirror
                if  doc_assembly.getObject( obj.ViewObject.Proxy.constraintObj_name ) == None:
                    debugPrint(2, 'removing %s which mirrors/links to a non-existent constraint' % obj.Name)
                    doc_assembly.removeObject( obj.Name ) #clean up for FreeCAD 0.15 which does not support the on-delete method
                elif not group_constraints_under_parts():
                     debugPrint(2, 'removing %s since group_constraints_under_parts=False' % obj.Name)
                     delattr( doc_assembly.getObject( obj.ViewObject.Proxy.constraintObj_name ),  'mirror_name' )
                     doc_assembly.removeObject( obj.Name )
            elif hasattr(obj,'Proxy') and isinstance( obj.Proxy, Proxy_importPart) and not isinstance( obj.ViewObject.Proxy, ImportedPartViewProviderProxy):
                obj.ViewObject.Proxy = ImportedPartViewProviderProxy()
                debugPrint(2, '%s.ViewObject.Proxy = ImportedPartViewProviderProxy()'%obj.Name)
        doc_assembly.recompute()
Example #7
0
 def Activated(self):
     from assembly2.solvers import solveConstraints
     constraintSystem = solveConstraints(FreeCAD.ActiveDocument)
     self.taskPanel = AnimateDegreesOfFreedomTaskPanel(constraintSystem)
     FreeCADGui.Control.showDialog(self.taskPanel)
Example #8
0
    def Activated(self):
        #disable proxies solving the system as their objects are updated
        doc_assembly = FreeCAD.ActiveDocument
        solve_assembly_constraints = False
        YesToAll_clicked = False
        for obj in doc_assembly.Objects:
            if hasattr(obj, 'sourceFile'):
                if not hasattr( obj, 'timeLastImport'):
                    obj.addProperty("App::PropertyFloat", "timeLastImport","importPart") #should default to zero which will force update.
                    obj.setEditorMode("timeLastImport",1)
                if not os.path.exists( obj.sourceFile ) and  path_rel_to_abs( obj.sourceFile ) is None:
                    debugPrint( 3, '%s.sourceFile %s is missing, attempting to repair it' % (obj.Name,  obj.sourceFile) )
                    replacement = None
                    aFolder, aFilename = posixpath.split( doc_assembly.FileName )
                    sParts = path_split( posixpath, obj.sourceFile)
                    debugPrint( 3, '  obj.sourceFile parts %s' % sParts )
                    replacement = None
                    previousRejects = []
                    while replacement == None and aFilename != '':
                        for i in reversed(range(len(sParts))):
                            newFn = aFolder
                            for j in range(i,len(sParts)):
                                newFn = posixpath.join( newFn,sParts[j] )
                            debugPrint( 4, '    checking %s' % newFn )
                            if os.path.exists( newFn ) and not newFn in previousRejects :
                                if YesToAll_clicked:
                                    replacement = newFn
                                    break
                                reply = QtGui.QMessageBox.question(
                                    QtGui.QApplication.activeWindow(), "%s source file not found" % obj.Name,
                                    "Unable to find\n  %s \nUse \n  %s\n instead?" % (obj.sourceFile, newFn) ,
                                    QtGui.QMessageBox.Yes | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)
                                if reply == QtGui.QMessageBox.Yes:
                                    replacement = newFn
                                    break
                                if reply == QtGui.QMessageBox.YesToAll:
                                    replacement = newFn
                                    YesToAll_clicked = True
                                    break
                                else:
                                    previousRejects.append( newFn )
                        aFolder, aFilename = posixpath.split( aFolder )
                    if replacement != None:
                        obj.sourceFile = replacement
                    else:
                        QtGui.QMessageBox.critical(  QtGui.QApplication.activeWindow(), "Source file not found", "update of %s aborted!\nUnable to find %s" % (obj.Name, obj.sourceFile) )
                        obj.timeLastImport = 0 #force update if users repairs link
                if path_rel_to_abs( obj.sourceFile ) is not None:
                    absolutePath = path_rel_to_abs( obj.sourceFile )
                    if os.path.getmtime( absolutePath ) > obj.timeLastImport:
                        importPart( absolutePath, obj.Name,  doc_assembly )
                        solve_assembly_constraints = True
                if os.path.exists( obj.sourceFile ):
                    if os.path.getmtime( obj.sourceFile ) > obj.timeLastImport:
                        importPart( obj.sourceFile, obj.Name,  doc_assembly )
                        solve_assembly_constraints = True

        if solve_assembly_constraints:
            solveConstraints( doc_assembly )
        # constraint mirror house keeping

        for obj in doc_assembly.Objects: #for adding creating mirrored constraints in old files
            if 'ConstraintInfo' in obj.Content:
                if doc_assembly.getObject( obj.Object1 ) == None or doc_assembly.getObject( obj.Object2 ) == None:
                    debugPrint(2, 'removing %s which refers to non-existent objects' % obj.Name)
                    doc_assembly.removeObject( obj.Name ) #required for FreeCAD 0.15 which does not support the on-delete method
                if group_constraints_under_parts():
                    if not hasattr( obj.ViewObject.Proxy, 'mirror_name'):
                        if isinstance( doc_assembly.getObject( obj.Object1 ).Proxy, Proxy_importPart) \
                                or isinstance( doc_assembly.getObject( obj.Object2 ).Proxy, Proxy_importPart):
                            debugPrint(2, 'creating mirror of %s' % obj.Name)
                            doc_assembly.getObject( obj.Object2 ).touch()
                            obj.ViewObject.Proxy.mirror_name = create_constraint_mirror(  obj, obj.ViewObject.Proxy.iconPath )
            elif 'ConstraintNfo' in obj.Content: #constraint mirror
                if  doc_assembly.getObject( obj.ViewObject.Proxy.constraintObj_name ) == None:
                    debugPrint(2, 'removing %s which mirrors/links to a non-existent constraint' % obj.Name)
                    doc_assembly.removeObject( obj.Name ) #clean up for FreeCAD 0.15 which does not support the on-delete method
                elif not group_constraints_under_parts():
                     debugPrint(2, 'removing %s since group_constraints_under_parts=False' % obj.Name)
                     delattr( doc_assembly.getObject( obj.ViewObject.Proxy.constraintObj_name ),  'mirror_name' )
                     doc_assembly.removeObject( obj.Name )
            elif hasattr(obj,'Proxy') and isinstance( obj.Proxy, Proxy_importPart) and not isinstance( obj.ViewObject.Proxy, ImportedPartViewProviderProxy):
                obj.ViewObject.Proxy = ImportedPartViewProviderProxy()
                debugPrint(2, '%s.ViewObject.Proxy = ImportedPartViewProviderProxy()'%obj.Name)
        doc_assembly.recompute()
    def generate_animation(self):
        preferences = FreeCAD.ParamGet(
            "User parameter:BaseApp/Preferences/Mod/Assembly2")
        org_auto_solve = preferences.GetBool(
            'autoSolveConstraintAttributesChanged', True)
        preferences.SetBool('autoSolveConstraintAttributesChanged', False)
        try:
            if hasattr(self, 'constraintAnimator'):
                self.constraintAnimator.stop()
            from assembly2.solvers import solveConstraints
            P = {}
            for p in animation_parameters:
                if hasattr(p, 'getValue'):
                    p.add_property_to_freecad_object()
                    P[p.name] = p.getValue()
            debugPrint(3, 'generate_animation parms %s' % P)
            constraint_to_animate = self.taskDialog.constraint_to_animate
            self.original_expressions = constraint_to_animate.ExpressionEngine  #[('angle', '12')]
            self.X = []
            if not hasattr(constraint_to_animate, 'a'):
                constraint_to_animate.addProperty({
                    'angle_between_planes':
                    'App::PropertyAngle',
                    'plane':
                    'App::PropertyDistance',
                    'circularEdge':
                    'App::PropertyDistance'
                }[constraint_to_animate.Type], 'a', "animationParameters")
                constraint_to_animate.setEditorMode('a', 2)
            attr_to_animate = {
                'angle_between_planes': 'angle',
                'plane': 'offset',
                'circularEdge': 'offset'
            }[constraint_to_animate.Type]
            attr_org_value = getattr(constraint_to_animate, attr_to_animate)
            constraint_to_animate.setExpression(attr_to_animate,
                                                P['animation_exp'])

            moduleVars['progressDialog'] = QtGui.QProgressDialog(
                "Generating Animation", "Cancel", 0, P['a_n'])
            p = moduleVars['progressDialog']
            p.setWindowModality(QtCore.Qt.WindowModal)
            p.forceShow()
            A = numpy.linspace(P['a_0'], P['a_1'], P['a_n'])
            for count, a in enumerate(A):
                if not p.wasCanceled():
                    p.setLabelText('solving %i/%i' % (count + 1, P['a_n']))
                    p.setValue(count)
                    debugPrint(3, 'solving constraint system for a=%1.1f' % a)
                    constraint_to_animate.a = a
                    FreeCAD.ActiveDocument.recompute(
                    )  #update other expersions
                    constraint_sys = solveConstraints(FreeCAD.ActiveDocument)
                    self.X.append(constraint_sys.variableManager.X.copy())
                    #variableManager.updateFreeCADValues( constraintSystem.variableManager.X )
            set_exp_to_none = True
            for ent in self.original_expressions:
                if ent[0] == attr_to_animate:
                    constraint_to_animate.setExpression(
                        attr_to_animate, ent[1])
                    set_exp_to_none = False
            if set_exp_to_none:
                constraint_to_animate.setExpression(attr_to_animate, None)
            setattr(constraint_to_animate, attr_to_animate, attr_org_value)
            if not p.wasCanceled():
                p.setValue(
                    P['a_n'])  #hopefully this will close the progress dialog
                if P['interp_method'] == 'none':
                    pass
                elif P['interp_method'] == 'linear':
                    self.X = linear_interp(self.X, A, P['n_interp'])
                elif P['interp_method'] == 'Cubic_Hermite_spline':
                    self.X = spline_interp(self.X, A, P['n_interp'])
                else:
                    raise NotImplemented

                self.playStopButton.setEnabled(True)
                self.constraintAnimator = ConstraintAnimator(
                    self.X, constraint_sys.variableManager)
                if P['play_after_generate']:
                    self.playStopButton_clicked()
        except:
            FreeCAD.Console.PrintError(traceback.format_exc())
        preferences.SetBool('autoSolveConstraintAttributesChanged',
                            org_auto_solve)
        debugPrint(3, 'done generating constraint animation')
 def reject(self):  #or more correctly close, given the button settings
     if hasattr(self.form, 'constraintAnimator'):
         self.form.constraintAnimator.stop()
         from assembly2.solvers import solveConstraints
         solveConstraints(FreeCAD.ActiveDocument)
     FreeCADGui.Control.closeDialog()
 def callSolveConstraints(self):
     from assembly2.solvers import solveConstraints
     solveConstraints( FreeCAD.ActiveDocument )
    def generate_animation( self ):
        preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Assembly2")
        org_auto_solve = preferences.GetBool('autoSolveConstraintAttributesChanged', True)
        preferences.SetBool('autoSolveConstraintAttributesChanged', False)
        try:
            if hasattr( self, 'constraintAnimator' ):
                 self.constraintAnimator.stop()
            from assembly2.solvers import solveConstraints
            P = {}
            for p in animation_parameters:
                if hasattr(p,'getValue'):
                    p.add_property_to_freecad_object()
                    P[p.name] = p.getValue()
            debugPrint(3, 'generate_animation parms %s' % P )
            constraint_to_animate = self.taskDialog.constraint_to_animate
            self.original_expressions = constraint_to_animate.ExpressionEngine #[('angle', '12')]
            self.X = []
            if not hasattr(constraint_to_animate, 'a'):
                constraint_to_animate.addProperty(
                    {'angle_between_planes':'App::PropertyAngle', 'plane':'App::PropertyDistance', 'circularEdge':'App::PropertyDistance'}[ constraint_to_animate.Type ],
                    'a',
                    "animationParameters"
                    )
                constraint_to_animate.setEditorMode( 'a', 2)
            attr_to_animate = {'angle_between_planes':'angle', 'plane':'offset', 'circularEdge':'offset'}[ constraint_to_animate.Type ]
            attr_org_value = getattr( constraint_to_animate, attr_to_animate)
            constraint_to_animate.setExpression( attr_to_animate, P['animation_exp'] )

            moduleVars['progressDialog'] = QtGui.QProgressDialog("Generating Animation", "Cancel", 0, P['a_n'])
            p = moduleVars['progressDialog']
            p.setWindowModality(QtCore.Qt.WindowModal)
            p.forceShow()
            A = numpy.linspace(P['a_0'],P['a_1'],P['a_n'])
            for count, a in enumerate(A):
                if not p.wasCanceled():
                    p.setLabelText( 'solving %i/%i' % (count+1, P['a_n']) )
                    p.setValue(count)
                    debugPrint(3, 'solving constraint system for a=%1.1f' % a )
                    constraint_to_animate.a = a
                    FreeCAD.ActiveDocument.recompute() #update other expersions
                    constraint_sys = solveConstraints( FreeCAD.ActiveDocument )
                    self.X.append( constraint_sys.variableManager.X.copy() )
                    #variableManager.updateFreeCADValues( constraintSystem.variableManager.X )
            set_exp_to_none = True
            for ent in self.original_expressions:
                if ent[0] == attr_to_animate:
                    constraint_to_animate.setExpression( attr_to_animate,ent[1] )
                    set_exp_to_none = False
            if set_exp_to_none:
                constraint_to_animate.setExpression( attr_to_animate, None )
            setattr( constraint_to_animate, attr_to_animate, attr_org_value )
            if not p.wasCanceled():
                p.setValue(P['a_n']) #hopefully this will close the progress dialog
                if P['interp_method'] == 'none':
                    pass
                elif P['interp_method'] == 'linear':
                    self.X = linear_interp( self.X, A , P['n_interp'] )
                elif P['interp_method'] == 'Cubic_Hermite_spline':
                    self.X = spline_interp( self.X, A , P['n_interp'] )
                else:
                    raise NotImplemented

                self.playStopButton.setEnabled( True )
                self.constraintAnimator = ConstraintAnimator( self.X, constraint_sys.variableManager)
                if P['play_after_generate']:
                    self.playStopButton_clicked()
        except:
            FreeCAD.Console.PrintError( traceback.format_exc() )
        preferences.SetBool('autoSolveConstraintAttributesChanged',org_auto_solve)
        debugPrint(3, 'done generating constraint animation' )
 def reject(self): #or more correctly close, given the button settings
     if hasattr( self.form, 'constraintAnimator' ):
         self.form.constraintAnimator.stop()
         from assembly2.solvers import solveConstraints
         solveConstraints( FreeCAD.ActiveDocument )
     FreeCADGui.Control.closeDialog()