예제 #1
0
class LinearArray(lattice2BaseFeature.LatticeFeature):
    "The Lattice LinearArray object"

    def derivedInit(self, obj):
        self.Type = "LatticeLinearArray"

        obj.addProperty("App::PropertyVector", "Dir", "Lattice Array",
                        "Vector that defines axis direction")
        obj.Dir = App.Vector(1, 0, 0)

        obj.addProperty(
            "App::PropertyVector", "Point", "Lattice Array",
            "Position of base (the point through which the axis passes, and from which positions of elements are measured)"
        )

        obj.addProperty("App::PropertyLink", "Link", "Lattice Array",
                        "Link to the axis (Edge1 is used for the axis).")
        obj.addProperty("App::PropertyString", "LinkSubelement",
                        "Lattice Array",
                        "subelement to take from axis link shape")

        obj.addProperty("App::PropertyBool", "Reverse", "Lattice Array",
                        "Set to true to reverse direction")

        obj.addProperty("App::PropertyBool", "DirIsDriven", "Lattice Array",
                        "If True, Dir property is driven by link.")
        obj.DirIsDriven = True

        obj.addProperty(
            "App::PropertyBool", "PointIsDriven", "Lattice Array",
            "If True, AxisPoint is not updated based on the link.")
        obj.PointIsDriven = True

        obj.addProperty(
            "App::PropertyEnumeration", "DrivenProperty", "Lattice Array",
            "Select, which property is to be driven by length of axis link.")
        obj.DrivenProperty = ['None', 'Span', 'SpanStart', 'SpanEnd', 'Step']
        obj.DrivenProperty = 'Span'

        obj.addProperty("App::PropertyEnumeration", "OrientMode",
                        "Lattice Array", "Orientation of elements")
        obj.OrientMode = ['None', 'Along axis']
        obj.OrientMode = 'Along axis'

        self.assureGenerator(obj)
        obj.ValuesSource = "Generator"
        obj.GeneratorMode = "StepN"
        obj.EndInclusive = True
        obj.SpanStart = 0.0
        obj.SpanEnd = 12.0
        obj.Step = 3.0
        obj.Count = 5.0

        self.assureProperties(obj)

    def updateReadonlyness(self, obj):
        link = screen(obj.Link)
        obj.setEditorMode("Dir", 1 if (link and obj.DirIsDriven) else 0)
        obj.setEditorMode("Point", 1 if (link and obj.PointIsDriven) else 0)
        obj.setEditorMode("DirIsDriven", 0 if link else 1)
        obj.setEditorMode("PointIsDriven", 0 if link else 1)
        obj.setEditorMode("DrivenProperty", 0 if link else 1)

        self.generator.updateReadonlyness()

    def assureGenerator(self, obj):
        '''Adds an instance of value series generator, if one doesn't exist yet.'''
        if hasattr(self, "generator"):
            return
        self.generator = ValueSeriesGenerator(obj)
        self.generator.addProperties(
            groupname="Lattice Array",
            groupname_gen="Lattice Series Generator",
            valuesdoc=
            "List of distances. Distance is measured from Point, along Dir, in millimeters.",
            valuestype="App::PropertyDistance")
        self.updateReadonlyness(obj)

    def assureProperties(self, selfobj):
        assureProperty(
            selfobj, "App::PropertyLinkSub", "SubLink",
            sublinkFromApart(screen(selfobj.Link), selfobj.LinkSubelement),
            "Lattice Array", "Mirror of Object+SubNames properties")

    def derivedExecute(self, obj):
        self.assureGenerator(obj)
        self.assureProperties(obj)
        self.updateReadonlyness(obj)

        # Apply links
        if screen(obj.Link):
            if lattice2BaseFeature.isObjectLattice(screen(obj.Link)):
                lattice2Executer.warning(
                    obj,
                    "For polar array, axis link is expected to be a regular shape. Lattice objct was supplied instead, it's going to be treated as a generic shape."
                )

            #resolve the link
            if len(obj.LinkSubelement) > 0:
                linkedShape = screen(obj.Link).Shape.getElement(
                    obj.LinkSubelement)
            else:
                linkedShape = screen(obj.Link).Shape

            #Type check
            if linkedShape.ShapeType != 'Edge':
                raise ValueError('Axis link must be an edge; it is ' +
                                 linkedShape.ShapeType + ' instead.')
            if type(linkedShape.Curve) is not Part.Line:
                raise ValueError('Axis link must be a line; it is ' +
                                 type(linkedShape.Curve) + ' instead.')

            #obtain
            start_point = linkedShape.valueAt(linkedShape.FirstParameter)
            end_point = linkedShape.valueAt(linkedShape.LastParameter)
            dir = end_point - start_point
            point = start_point if not obj.Reverse else end_point

            if obj.DirIsDriven:
                obj.Dir = dir
            if obj.PointIsDriven:
                obj.Point = point
            if obj.DrivenProperty != 'None':
                if obj.DrivenProperty == 'Span':
                    propname = "SpanEnd"
                    obj.SpanEnd = obj.SpanStart + App.Units.Quantity(
                        'mm') * dir.Length
                else:
                    propname = obj.DrivenProperty
                    setattr(obj, propname, dir.Length)
                if self.generator.isPropertyControlledByGenerator(propname):
                    lattice2Executer.warning(
                        obj, "Property " + propname +
                        " is driven by both generator and link. Generator has priority."
                    )

        # Generate series of values
        self.generator.execute()
        values = [float(strv) for strv in obj.Values]

        #Apply reversal
        if obj.Reverse:
            obj.Dir = obj.Dir * (-1.0)
            if not (obj.DirIsDriven and screen(obj.Link)):
                obj.Reverse = False

        # precompute orientation
        if obj.OrientMode == 'Along axis':
            ori = lattice2GeomUtils.makeOrientationFromLocalAxes(
                ZAx=obj.Dir).multiply(
                    lattice2GeomUtils.makeOrientationFromLocalAxes(
                        ZAx=App.Vector(1, 0, 0), XAx=App.Vector(0, 0, 1)))
        else:
            ori = App.Rotation()

        dir = obj.Dir
        dir.normalize()

        # Make the array
        output = []  # list of placements
        for v in values:
            output.append(App.Placement(obj.Point + obj.Dir * v, ori))

        return output

    def onChanged(self, selfobj,
                  prop):  #prop is a string - name of the property
        # synchronize SubLink and Object+SubNames properties
        syncSublinkApart(selfobj, prop, 'SubLink', 'Link', 'LinkSubelement')
        return lattice2BaseFeature.LatticeFeature.onChanged(
            self, selfobj, prop)
예제 #2
0
class LinearArray(lattice2BaseFeature.LatticeFeature):
    "The Lattice LinearArray object"
    def derivedInit(self,obj):
        self.Type = "LatticeLinearArray"

        obj.addProperty("App::PropertyVector","Dir","Lattice Array","Vector that defines axis direction")  
        obj.Dir = App.Vector(1,0,0)
        
        obj.addProperty("App::PropertyVector","Point","Lattice Array","Position of base (the point through which the axis passes, and from which positions of elements are measured)")  
        
        obj.addProperty("App::PropertyLink","Link","Lattice Array","Link to the axis (Edge1 is used for the axis).")  
        obj.addProperty("App::PropertyString","LinkSubelement","Lattice Array","subelement to take from axis link shape")

        obj.addProperty("App::PropertyBool","Reverse","Lattice Array","Set to true to reverse direction")

        obj.addProperty("App::PropertyBool","DirIsDriven","Lattice Array","If True, Dir property is driven by link.")
        obj.DirIsDriven = True

        obj.addProperty("App::PropertyBool","PointIsDriven","Lattice Array","If True, AxisPoint is not updated based on the link.")
        obj.PointIsDriven = True

        obj.addProperty("App::PropertyEnumeration","DrivenProperty","Lattice Array","Select, which property is to be driven by length of axis link.")
        obj.DrivenProperty = ['None','Span','SpanStart','SpanEnd','Step']
        obj.DrivenProperty = 'Span'
                        
        obj.addProperty("App::PropertyEnumeration","OrientMode","Lattice Array","Orientation of elements")
        obj.OrientMode = ['None','Along axis']
        obj.OrientMode = 'Along axis'
        
        self.assureGenerator(obj)
        obj.ValuesSource = "Generator"
        obj.GeneratorMode = "StepN"
        obj.EndInclusive = True
        obj.SpanStart = 0.0
        obj.SpanEnd = 12.0
        obj.Step = 3.0
        obj.Count = 5.0

    def updateReadonlyness(self, obj):
        obj.setEditorMode("Dir", 1 if (obj.Link and obj.DirIsDriven) else 0)
        obj.setEditorMode("Point", 1 if (obj.Link and obj.PointIsDriven) else 0)
        obj.setEditorMode("DirIsDriven", 0 if obj.Link else 1)
        obj.setEditorMode("PointIsDriven", 0 if obj.Link else 1)
        obj.setEditorMode("DrivenProperty", 0 if obj.Link else 1)
        
        self.generator.updateReadonlyness()

    def assureGenerator(self, obj):
        '''Adds an instance of value series generator, if one doesn't exist yet.'''
        if hasattr(self,"generator"):
            return
        self.generator = ValueSeriesGenerator(obj)
        self.generator.addProperties(groupname= "Lattice Array", 
                                     groupname_gen= "Lattice Series Generator", 
                                     valuesdoc= "List of distances. Distance is measured from Point, along Dir, in millimeters.",
                                     valuestype= "App::PropertyDistance")
        self.updateReadonlyness(obj)
        
        

    def derivedExecute(self,obj):
        self.assureGenerator(obj)
        self.updateReadonlyness(obj)

        # Apply links
        if obj.Link:
            if lattice2BaseFeature.isObjectLattice(obj.Link):
                lattice2Executer.warning(obj,"For polar array, axis link is expected to be a regular shape. Lattice objct was supplied instead, it's going to be treated as a generic shape.")
            
            #resolve the link
            if len(obj.LinkSubelement) > 0:
                linkedShape = obj.Link.Shape.getElement(obj.LinkSubelement)
            else:
                linkedShape = obj.Link.Shape
            
            #Type check
            if linkedShape.ShapeType != 'Edge':
                raise ValueError('Axis link must be an edge; it is '+linkedShape.ShapeType+' instead.')
            if type(linkedShape.Curve) is not Part.Line:
                raise ValueError('Axis link must be a line; it is '+type(linkedShape.Curve)+' instead.')
            
            #obtain
            dir = linkedShape.Curve.EndPoint - linkedShape.Curve.StartPoint
            point = linkedShape.Curve.StartPoint if not obj.Reverse else linkedShape.Curve.EndPoint
            
            if obj.DirIsDriven:
                obj.Dir = dir
            if obj.PointIsDriven:
                obj.Point = point
            if obj.DrivenProperty != 'None':
                if obj.DrivenProperty == 'Span':
                    propname = "SpanEnd"
                    obj.SpanEnd = obj.SpanStart + App.Units.Quantity('mm')*dir.Length
                else:
                    propname = obj.DrivenProperty
                    setattr(obj, propname, dir.Length)
                if self.generator.isPropertyControlledByGenerator(propname):
                    lattice2Executer.warning(obj, "Property "+propname+" is driven by both generator and link. Generator has priority.")

        
        # Generate series of values
        self.generator.execute()
        values = [float(strv) for strv in obj.Values]
        
        #Apply reversal
        if obj.Reverse:
            obj.Dir = obj.Dir*(-1.0)
            if not(obj.DirIsDriven and obj.Link):
                obj.Reverse = False

        # precompute orientation
        if obj.OrientMode == 'Along axis':
            ori = lattice2GeomUtils.makeOrientationFromLocalAxes(ZAx= obj.Dir).multiply(
                    lattice2GeomUtils.makeOrientationFromLocalAxes(ZAx= App.Vector(1,0,0), XAx= App.Vector(0,0,1)) )
        else:
            ori = App.Rotation()
        
        dir = obj.Dir
        dir.normalize()
        
        # Make the array
        output = [] # list of placements
        for v in values:
            output.append( App.Placement(obj.Point + obj.Dir*v, ori) )
            
        return output