def updateData(self, feature, prop): r"""If a property of the handled feature has changed, we have the chance to handle this here See Also -------- https://www.freecadweb.org/wiki/Scripted_objects """ debug("ViewProviderAnchor/updateData") p = feature.getPropertyByName("p") u = feature.getPropertyByName("u") v = feature.getPropertyByName("v") self.transform.translation.setValue((p[0], p[1], p[2])) at = anchor_transformation(p0=(0, 0, 0), u0=(0, -1, 0), v0=(0, 0, 1), p1=(p[0], p[1], p[2]), u1=(u[0], u[1], u[2]), v1=(v[0], v[1], v[2])) t = translation_from_matrix(at) self.transform.translation.setValue((t[0], t[1], t[2])) angle, direction, point = rotation_from_matrix(at) # print("angle : %f" % angle) # print("direction : %s" % str(direction)) # print("point : %s" % str(point)) self.transform.rotation.setValue(coin.SbVec3f(direction), angle)
def execute(self, fp): r"""Do something when doing a recomputation, this method is mandatory""" debug("Recompute Anchor feature\n") p, u, v = puv(fp.parent.Shape.getElement(fp.name_sub_element)) fp.p = App.Vector(p[0], p[1], p[2]) fp.u = App.Vector(u[0], u[1], u[2]) fp.v = App.Vector(v[0], v[1], v[2])
def Activated(self): r"""The Open anchorable object Command was activated""" dialog = QtGui.QFileDialog.getOpenFileName( filter="Stepzip files (*.stepzip)") # todo : open logic # unzip # open the step # make it an anchorable object # add the anchors to the anchorable object debug("Will open %s" % str(dialog))
def onChanged(self, vp, prop): r"""Here we can do something when a single property got changed""" debug("Change property of ViewProvideAnchor: " + str(prop) + "\n") if prop == "ColorU": cu = vp.getPropertyByName("ColorU") self.color_u.rgb.setValue(cu[0], cu[1], cu[2]) if prop == "ColorV": cv = vp.getPropertyByName("ColorV") self.color_v.rgb.setValue(cv[0], cv[1], cv[2])
def Activated(self): r"""The Save anchorable object Command was activated""" # selection = Gui.Selection.getSelection() selection_ex = Gui.Selection.getSelectionEx() debug("len selection_ex = %i" % len(selection_ex)) if len(selection_ex) != 1: msg = "Anchors : " \ "Select only 1 anchorable object to save" error(msg) return else: # https://forum.freecadweb.org/viewtopic.php?t=7249 unique_selection = selection_ex[0] selected_object = unique_selection.Object debug(" Selection : %s || %s" % (selected_object, selected_object.Shape.ShapeType)) # check is anchorable object if is_anchorable_object(selected_object): dialog = QtGui.QFileDialog.getSaveFileName( filter="Stepzip files (*.stepzip)") # save shape as step stepzip_path = dialog[0] stepfile = splitext(stepzip_path)[0] + ".stp" anchorsfile = splitext(stepzip_path)[0] + ".anchors" selected_object.Shape.exportStep(stepfile) # save anchors file (+ feature attachment) # TODO : save more info about anchor (sub element link) anchors_descs = [] for anchor in selected_object.Anchors: anchors_descs.append("%s %f,%f,%f,%f,%f,%f,%f,%f,%f" % (anchor.Label, anchor.p[0], anchor.p[1], anchor.p[2], anchor.u[0], anchor.u[1], anchor.u[2], anchor.v[0], anchor.v[1], anchor.v[2])) with open(anchorsfile, 'w') as f: f.write("\n".join(anchors_descs)) # zip it to a stepzip create_stepzip(stepfile, anchorsfile) info("Anchorable object saved to %s" % dialog[0]) else: error("The object to save should be an anchorable object")
def Activated(self): r"""The command has been clicked""" debug("CommandAnchorableObjectAdd, Activated") sel = Gui.Selection.getSelectionEx() try: if len(sel) != 1: raise Exception("Select one shape to make it anchorable") try: App.ActiveDocument.openTransaction("Anchorable Object") obj = make_anchorable_object_feature() obj.Base = sel[0].Object obj.Base.ViewObject.hide() obj.Proxy.execute(obj) finally: App.ActiveDocument.commitTransaction() except Exception as err: from PySide import QtGui mb = QtGui.QMessageBox() mb.setIcon(mb.Icon.Warning) mb.setText(err.message) mb.setWindowTitle("Anchorable Object") mb.exec_()
def Activated(self): r"""The Add Anchor Command was activated""" # selection = Gui.Selection.getSelection() selection_ex = Gui.Selection.getSelectionEx() debug("len selection_ex = %i" % len(selection_ex)) if len(selection_ex) != 1: msg = "Anchors : " \ "Select feature(s) on only 1 solid to add anchors to" error(msg) return else: # https://forum.freecadweb.org/viewtopic.php?t=7249 unique_selection = selection_ex[0] selected_object = unique_selection.Object debug(" Selection : %s || %s" % (selected_object, selected_object.Shape.ShapeType)) subselected_objects = unique_selection.SubObjects for i, subselected_object in enumerate(subselected_objects): debug("SubSelection : %s || %s" % (subselected_object, type(subselected_object))) p, u, v = puv(subselected_object) # make_anchor_feature(p, u, v) print("SubElementName : %s" % unique_selection.SubElementNames[0]) a = App.ActiveDocument.addObject("App::FeaturePython", "Anchor") Anchor(a, p, u, v, topo_element=(unique_selection.Object, unique_selection.SubElementNames[i])) ViewProviderAnchor(a.ViewObject) # -- Add the anchor to the App::PropertyLinkList # of the selected AnchorableObject -- try: l = selected_object.Anchors l.append(a) selected_object.Anchors = l except AttributeError: msg = "Are you adding anchors to an AnchorableObject?" error(msg)
def puv(subselected_object): # if isinstance(subselected_object, Part.Solid): # debug("It is a Solid") # elif isinstance(subselected_object, Part.Shell): # debug("It is a Shell") if isinstance(subselected_object, Part.Face): debug("It is a Face") face = subselected_object p, u, v = puv_from_face(face) elif isinstance(subselected_object, Part.Wire): debug("It is a Wire") elif isinstance(subselected_object, Part.Edge): debug("It is an Edge") debug('TYPE : %s' % type(subselected_object.Curve)) if str(type(subselected_object.Curve)) == "<type 'Part.Circle'>": debug("it is a circle") edge = subselected_object p, u, v = puv_from_circular_edge(edge) elif str(type(subselected_object.Curve)) == "<type 'Part.Line'>": debug("it is a line") else: # known other possibilities # - <type 'Part.BSplineCurve'> debug("it is NOT a circle and NOR a line") elif isinstance(subselected_object, Part.Vertex): debug("It is a Vertex") else: debug("What is that?") return p, u, v
def onChanged(self, feature, prop): r"""Do something when a property has changed""" debug("Change property: " + str(prop) + "\n") if prop in ['Base']: self.execute(feature) feature.Base.ViewObject.hide()
def attach(self, vobj): r"""Setup the scene sub-graph of the view provider, this method is mandatory See Also -------- https://www.freecadweb.org/wiki/Scripted_objects """ debug("AnchorViewProvider/attach") self.shaded = coin.SoSeparator() self.wireframe = coin.SoSeparator() # group u cone and cylinder self.group_u = coin.SoSeparator() self.color_u = coin.SoBaseColor() self.group_cyl_u = coin.SoSeparator() self.transform_cyl_u = coin.SoTransform() self.group_cone_u = coin.SoSeparator() self.transform_cone_u = coin.SoTransform() # group v cone and cylinder self.group_v = coin.SoSeparator() self.transform_v = coin.SoTransform() self.color_v = coin.SoBaseColor() self.group_cyl_v = coin.SoSeparator() self.transform_cyl_v = coin.SoTransform() self.group_cone_v = coin.SoSeparator() self.transform_cone_v = coin.SoTransform() # global self.scale = coin.SoScale() self.scale.scaleFactor.setValue(1., 1., 1.) self.transform = coin.SoTransform() # arrow dimensions self.arrow_length = 1 cone_cyl_ratio = 0.2 cyl_radius_ratio = 0.05 cone_base_radius_ratio = 0.1 # The cylinder is created from its middle at the origin # -> compensation self.transform_cyl_u.translation.setValue( (0., self.arrow_length * (1 - cone_cyl_ratio) / 2, 0.)) self.transform_cone_u.translation.setValue( (0., self.arrow_length * (1 - cone_cyl_ratio) + self.arrow_length * cone_cyl_ratio / 2, 0.)) self.transform_cyl_v.translation.setValue( (0., self.arrow_length * (1 - cone_cyl_ratio) / 2, 0.)) self.transform_cone_v.translation.setValue( (0., self.arrow_length * (1 - cone_cyl_ratio) + self.arrow_length * cone_cyl_ratio / 2, 0.)) # put v at 90 degrees self.transform_v.center.setValue((0, 0, 0)) self.transform_v.rotation.setValue(coin.SbVec3f((1, 0, 0)), math.pi / 2) # Cone and cylinder creation from dimensions cone_u = coin.SoCone() cone_u.height.setValue(self.arrow_length * cone_cyl_ratio) cone_u.bottomRadius.setValue(self.arrow_length * cone_base_radius_ratio) cylinder_u = coin.SoCylinder() cylinder_u.radius.setValue(self.arrow_length * cyl_radius_ratio) cylinder_u.height.setValue(self.arrow_length * (1 - cone_cyl_ratio)) cone_v = coin.SoCone() cone_v.height.setValue(self.arrow_length * cone_cyl_ratio) cone_v.bottomRadius.setValue(self.arrow_length * cone_base_radius_ratio) cylinder_v = coin.SoCylinder() cylinder_v.radius.setValue(self.arrow_length * cyl_radius_ratio) cylinder_v.height.setValue(self.arrow_length * (1 - cone_cyl_ratio)) # group_cyl_u self.group_cyl_u.addChild(self.transform_cyl_u) self.group_cyl_u.addChild(cylinder_u) # group_cone_u self.group_cone_u.addChild(self.transform_cone_u) self.group_cone_u.addChild(cone_u) # group_u self.group_u.addChild(self.color_u) self.group_u.addChild(self.group_cyl_u) self.group_u.addChild(self.group_cone_u) # group_cyl_v self.group_cyl_v.addChild(self.transform_cyl_v) self.group_cyl_v.addChild(cylinder_v) # group_cone_v self.group_cone_v.addChild(self.transform_cone_v) self.group_cone_v.addChild(cone_v) # group_v self.group_v.addChild(self.transform_v) self.group_v.addChild(self.color_v) self.group_v.addChild(self.group_cyl_v) self.group_v.addChild(self.group_cone_v) # ** shaded ** self.shaded.addChild(self.transform) self.shaded.addChild(self.scale) self.shaded.addChild(self.group_u) self.shaded.addChild(self.group_v) vobj.addDisplayMode(self.shaded, "Shaded") # ** wireframe ** style = coin.SoDrawStyle() style.style = coin.SoDrawStyle.LINES self.wireframe.addChild(style) self.wireframe.addChild(self.transform) self.wireframe.addChild(self.scale) self.wireframe.addChild(self.group_u) self.wireframe.addChild(self.group_v) vobj.addDisplayMode(self.wireframe, "Wireframe") self.onChanged(vobj, "ColorU") self.onChanged(vobj, "ColorV")
def onChanged(self, fp, prop): r"""Do something when a property has changed""" debug("Change property of Anchor: " + str(prop) + "\n")