Ejemplo n.º 1
0
def _svg_dimension(obj, plane, scale, linewidth, fontsize,
                   stroke, pointratio, techdraw, rotation):
    """Return the SVG representation of a linear dimension."""
    if not App.GuiUp:
        _wrn("'{}': SVG can only be generated "
             "in GUI mode".format(obj.Label))
        return ""

    if not hasattr(obj.ViewObject, "Proxy") or not obj.ViewObject.Proxy:
        _err("'{}': doesn't have Proxy, "
             "SVG cannot be generated".format(obj.Label))
        return ""

    vobj = obj.ViewObject
    prx = vobj.Proxy

    if not hasattr(prx, "p1"):
        _err("'{}': doesn't have points, "
             "SVG cannot be generated".format(obj.Label))
        return ""

    ts = len(prx.string) * vobj.FontSize.Value / 4.0
    rm = (prx.p3 - prx.p2).Length/2.0 - ts

    _diff32 = prx.p3 - prx.p2
    _diff23 = prx.p2 - prx.p3

    _v32 = DraftVecUtils.scaleTo(_diff32, rm)
    _v23 = DraftVecUtils.scaleTo(_diff23, rm)

    p2a = get_proj(prx.p2 + _v32, plane)
    p2b = get_proj(prx.p3 + _v23, plane)
    p1 = get_proj(prx.p1, plane)
    p2 = get_proj(prx.p2, plane)
    p3 = get_proj(prx.p3, plane)
    p4 = get_proj(prx.p4, plane)

    tbase = get_proj(prx.tbase, plane)
    r = prx.textpos.rotation.getValue().getValue()
    _rv = App.Rotation(r[0], r[1], r[2], r[3])
    rv = _rv.multVec(App.Vector(1, 0, 0))
    angle = -DraftVecUtils.angle(get_proj(rv, plane))
    # angle = -DraftVecUtils.angle(p3.sub(p2))

    svg = ''
    nolines = False
    if hasattr(vobj, "ShowLine"):
        if not vobj.ShowLine:
            nolines = True

    # drawing lines
    if not nolines:
        svg += '<path '

    if vobj.DisplayMode == "2D":
        tangle = angle
        if tangle > math.pi/2:
            tangle = tangle-math.pi
        # elif (tangle <= -math.pi/2) or (tangle > math.pi/2):
        #    tangle = tangle + math.pi

        if rotation != 0:
            # print("dim: tangle:", tangle,
            #       " rot: ", rotation,
            #       " text: ", prx.string)
            if abs(tangle + math.radians(rotation)) < 0.0001:
                tangle += math.pi
                _v = App.Vector(0, 2.0/scale, 0)
                _rot = DraftVecUtils.rotate(_v, tangle)
                tbase = tbase + _rot

        if not nolines:
            svg += 'd="M ' + str(p1.x) + ' ' + str(p1.y) + ' '
            svg += 'L ' + str(p2.x) + ' ' + str(p2.y) + ' '
            svg += 'L ' + str(p3.x) + ' ' + str(p3.y) + ' '
            svg += 'L ' + str(p4.x) + ' ' + str(p4.y) + '" '
    else:
        tangle = 0
        if rotation != 0:
            tangle = -math.radians(rotation)

        tbase = tbase + App.Vector(0, -2.0/scale, 0)
        if not nolines:
            svg += 'd="M ' + str(p1.x) + ' ' + str(p1.y) + ' '
            svg += 'L ' + str(p2.x) + ' ' + str(p2.y) + ' '
            svg += 'L ' + str(p2a.x) + ' ' + str(p2a.y) + ' '
            svg += 'M ' + str(p2b.x) + ' ' + str(p2b.y) + ' '
            svg += 'L ' + str(p3.x) + ' ' + str(p3.y) + ' '
            svg += 'L ' + str(p4.x) + ' ' + str(p4.y) + '" '

    if not nolines:
        svg += 'fill="none" stroke="'
        svg += stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:' + str(linewidth)
        svg += ';stroke-miterlimit:4;stroke-dasharray:none" '
        svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" '
        svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" '
        svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"'
        svg += '/>\n'

        # drawing dimension and extension lines overshoots
        if hasattr(vobj, "DimOvershoot") and vobj.DimOvershoot.Value:
            shootsize = vobj.DimOvershoot.Value/pointratio
            svg += get_overshoot(p2, shootsize, stroke,
                                 linewidth, angle)
            svg += get_overshoot(p3, shootsize, stroke,
                                 linewidth, angle + math.pi)

        if hasattr(vobj, "ExtOvershoot") and vobj.ExtOvershoot.Value:
            shootsize = vobj.ExtOvershoot.Value/pointratio
            shootangle = -DraftVecUtils.angle(p1 - p2)
            svg += get_overshoot(p2, shootsize, stroke,
                                 linewidth, shootangle)
            svg += get_overshoot(p3, shootsize, stroke,
                                 linewidth, shootangle)

        # drawing arrows
        if hasattr(vobj, "ArrowType"):
            arrowsize = vobj.ArrowSize.Value/pointratio
            if hasattr(vobj, "FlipArrows"):
                if vobj.FlipArrows:
                    angle = angle + math.pi

            svg += get_arrow(obj,
                             vobj.ArrowType,
                             p2, arrowsize, stroke, linewidth,
                             angle)
            svg += get_arrow(obj,
                             vobj.ArrowType,
                             p3, arrowsize, stroke, linewidth,
                             angle + math.pi)

    # drawing text
    svg += svgtext.get_text(plane, techdraw,
                            stroke, fontsize, vobj.FontName,
                            tangle, tbase, prx.string)

    return svg
Ejemplo n.º 2
0
def CreateFromTemplate(job, template):
    if template.get('version') and 1 == int(template['version']):
        stockType = template.get('create')
        if stockType:
            placement = None
            posX = template.get('posX')
            posY = template.get('posY')
            posZ = template.get('posZ')
            rotX = template.get('rotX')
            rotY = template.get('rotY')
            rotZ = template.get('rotZ')
            rotW = template.get('rotW')
            if posX is not None and posY is not None and posZ is not None and rotX is not None and rotY is not None and rotZ is not None and rotW is not None:
                pos = FreeCAD.Vector(float(posX), float(posY), float(posZ))
                rot = FreeCAD.Rotation(float(rotX), float(rotY), float(rotZ),
                                       float(rotW))
                placement = FreeCAD.Placement(pos, rot)
            elif posX is not None or posY is not None or posZ is not None or rotX is not None or rotY is not None or rotZ is not None or rotW is not None:
                PathLog.warning(
                    translate(
                        'PathStock',
                        'Corrupted or incomplete placement information in template - ignoring'
                    ))

            if stockType == StockType.FromBase:
                xneg = template.get('xneg')
                xpos = template.get('xpos')
                yneg = template.get('yneg')
                ypos = template.get('ypos')
                zneg = template.get('zneg')
                zpos = template.get('zpos')
                neg = None
                pos = None
                if xneg is not None and xpos is not None and yneg is not None and ypos is not None and zneg is not None and zpos is not None:
                    neg = FreeCAD.Vector(
                        FreeCAD.Units.Quantity(xneg).Value,
                        FreeCAD.Units.Quantity(yneg).Value,
                        FreeCAD.Units.Quantity(zneg).Value)
                    pos = FreeCAD.Vector(
                        FreeCAD.Units.Quantity(xpos).Value,
                        FreeCAD.Units.Quantity(ypos).Value,
                        FreeCAD.Units.Quantity(zpos).Value)
                elif xneg is not None or xpos is not None or yneg is not None or ypos is not None or zneg is not None or zpos is not None:
                    PathLog.error(
                        translate(
                            'PathStock',
                            'Corrupted or incomplete specification for creating stock from base - ignoring extent'
                        ))
                return CreateFromBase(job, neg, pos, placement)

            if stockType == StockType.CreateBox:
                PathLog.track(' create box')
                length = template.get('length')
                width = template.get('width')
                height = template.get('height')
                extent = None
                if length is not None and width is not None and height is not None:
                    PathLog.track('  have extent')
                    extent = FreeCAD.Vector(
                        FreeCAD.Units.Quantity(length).Value,
                        FreeCAD.Units.Quantity(width).Value,
                        FreeCAD.Units.Quantity(height).Value)
                elif length is not None or width is not None or height is not None:
                    PathLog.error(
                        translate(
                            'PathStock',
                            'Corrupted or incomplete size for creating a stock box - ignoring size'
                        ))
                else:
                    PathLog.track(
                        "  take placement (%s) and extent (%s) from model" %
                        (placement, extent))
                return CreateBox(job, extent, placement)

            if stockType == StockType.CreateCylinder:
                radius = template.get('radius')
                height = template.get('height')
                if radius is not None and height is not None:
                    pass
                elif radius is not None or height is not None:
                    radius = None
                    height = None
                    PathLog.error(
                        translate(
                            'PathStock',
                            'Corrupted or incomplete size for creating a stock cylinder - ignoring size'
                        ))
                return CreateCylinder(job, radius, height, placement)

            PathLog.error(
                translate('PathStock',
                          'Unsupported stock type named {}').format(stockType))
        else:
            PathLog.error(
                translate('PathStock',
                          'Unsupported PathStock template version {}').format(
                              template.get('version')))
        return None
EPS_C = EPS * (-0.5)

cote_maximal = 2 + 8 + 8 + 8 + 86 + 8 + 8 + 8 + 2

hauteur_maximal = 2

# part_support_laser_cutting
part_support_laser_cutting = Part.makeCylinder(cote_maximal/2, hauteur_maximal)

# holes for fixing the electrodes
degre = 180
for i in range(int(360/degre)):
    hole = Part.makeCylinder(4, hauteur_maximal)
    radius = 50/2 - 4 - 4
    alpha=(i*degre*math.pi)/180
    hole_vector = FreeCAD.Vector(radius*math.cos(alpha), radius*math.sin(alpha), 0)
    hole.translate(hole_vector)
    part_support_laser_cutting = part_support_laser_cutting.cut(hole)

# holes for reducing the cost
degre = 15
for i in range(int(360/degre)):
    hole = Part.makeCylinder(4, hauteur_maximal)
    radius = 86/2 + 8 + 4
    alpha=(i*degre*math.pi)/180
    hole_vector = FreeCAD.Vector(radius*math.cos(alpha), radius*math.sin(alpha), 0)
    hole.translate(hole_vector)
    part_support_laser_cutting = part_support_laser_cutting.cut(hole)

Part.show(part_support_laser_cutting)
Ejemplo n.º 4
0
    def settarget4(self):
        '''rotate neighbors'''

        print "settarget 4"

        dok = self.helperDok()
        pl = len(self.points)
        self.dial.setMaximum(pl - 1)
        pos = self.dial.value()

        if pos == 0: lpos = pl - 1
        else: lpos = pos - 1

        if pos == pl - 1: rpos = 0
        else: rpos = pos + 1
        #		print ('pl,pos,lpos,rpos',pl,pos,lpos,rpos)

        t = self.points[pos]
        t1 = self.points[pos - 1]
        t2 = self.points[pos + 1]

        dt1 = t1 - t
        dt2 = t2 - t
        print(dt1, dt2)

        # rotation
        p2 = FreeCAD.Placement()
        #p2.Rotation=FreeCAD.Rotation(FreeCAD.Vector(0,0,1),za).multiply(FreeCAD.Rotation(FreeCAD.Vector(0,1,0),ya).multiply(FreeCAD.Rotation(FreeCAD.Vector(1,0,0),xa)))
        ef = self.ef
        kr = ef.mouseWheel * FreeCAD.ParamGet(
            'User parameter:Plugins/nurbs').GetFloat("MoveWheelStep", 1)
        p2.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), kr)

        print(t1, t2)
        ph = FreeCAD.Placement()
        ph.Base = dt1
        drt1 = p2.multiply(ph).Base
        t1 = t + drt1

        ph = FreeCAD.Placement()
        ph.Base = dt2
        drt2 = p2.multiply(ph).Base
        t2 = t + drt2

        print(t1, t2)
        print "kilo"
        self.target(dok, coordlist=[t1, t, t2])

        #		try: dok.Sphere
        #		except:
        #			s=dok.addObject("Part::Sphere","Sphere")
        #			s.Radius=10000000
        #			s.ViewObject.Selectable=False
        #			s.ViewObject.ShapeColor=(1.,1.,1.)
        #			s.ViewObject.DisplayMode = u"Shaded"
        #			s.ViewObject.DisplayMode = u"Shaded"

        # create or get traget curve
        try:
            bb = dok.TargetCurve
            bax = dok.TargetExtra

        except:
            bb = dok.addObject('Part::Feature', 'TargetCurve')
            bax = dok.addObject('Part::Feature', 'TargetExtra')

        bax.ViewObject.LineColor = (1.0, 1.0, 0.0)

        pp = self.points

        pp2 = pp[:pos - 1] + [t1, t, t2] + pp[pos + 2:]
        print("lnes", len(pp), len(pp2))

        # bspline curve
        bs = dok.BSpline.Shape.Edge1.Curve.copy()
        bs.setPole(pos, FreeCAD.Vector(t1))
        bs.setPole(pos + 1, FreeCAD.Vector(t))
        bs.setPole(pos + 2, FreeCAD.Vector(t2))
        dok.BSpline.Shape = bs.toShape()
        sss = bs.toShape()

        # pole polygon
        pol = Part.makePolygon(pp2 + [pp2[0]])
        #		bb.Shape=pol

        pp3 = []
        ppax = []

        print "wwww"

        if self.source == 'Backbone':
            xV = FreeCAD.Vector(100, 0, 0)
            yV = FreeCAD.Vector(0, 100, 0)
            zV = FreeCAD.Vector(0, 0, 141)

            source = self.getsource()
            needle = source.InList[0]
            curvea, bba, scaler, twister = needle.Proxy.Model()

            for i, p in enumerate(pp2):
                # print (i,twister[i],scaler[i])
                [xa, ya, za] = twister[i]

                if pos == i:
                    xa += self.rotx
                    ya += self.roty
                    za += self.rotz

                if pos == i:
                    xa = self.rotx
                    ya = self.roty
                    za = self.rotz

                p2 = FreeCAD.Placement()
                p2.Rotation = FreeCAD.Rotation(FreeCAD.Vector(
                    0, 0, 1), za).multiply(
                        FreeCAD.Rotation(FreeCAD.Vector(0, 1, 0), ya).multiply(
                            FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), xa)))

                ph = FreeCAD.Placement()
                ph.Base = xV
                xR = p2.multiply(ph).Base
                ph = FreeCAD.Placement()
                ph.Base = yV
                yR = p2.multiply(ph).Base
                ph = FreeCAD.Placement()
                ph.Base = zV
                zR = p2.multiply(ph).Base

                p = FreeCAD.Vector(p)

                if 1:
                    pp = Part.makePolygon([p, p + xR, p + xR + yR, p])
                    ps = Part.Face(pp)
                    ppax.append(ps)
                    pp = Part.makePolygon([p, p + yR, p + xR + yR, p])
                    ppax.append(Part.Face(pp))
                    pp = Part.makePolygon([p, p + zR, p + xR + yR, p])
                    ppax.append(Part.Face(pp))

        # all together
        bb.Shape = Part.Compound([pol])
        if ppax <> []:
            bax.Shape = Part.Compound(ppax + [bs.toShape(), sss])

        dok.recompute()

        bb.ViewObject.LineColor = (1.0, 0.6, .0)
        bb.ViewObject.LineWidth = 1
        bb.ViewObject.PointColor = (.8, 0.4, .0)
        bb.ViewObject.PointSize = 8
        bax.ViewObject.Selectable = False

        col = []
        for i in range(len(bax.Shape.Faces)):
            tt = i % 3
            if tt == 0: col.append((1., 0., 0.))
            elif tt == 1: col.append((0., 1., 0.))
            else: col.append((0., 0., 1.))
        bax.ViewObject.DiffuseColor = col
Ejemplo n.º 5
0
def addLine(start, angle, length):
    result = App.Vector(start.x + length * math.cos(angle),
                        start.y + length * math.sin(angle), start.z)
    return result
Ejemplo n.º 6
0
    def execute(self, obj):
        "creates the structure shape"

        import Part, DraftGeomUtils

        if self.clone(obj):
            return

        normal, length, width, height = self.getDefaultValues(obj)

        # creating base shape
        pl = obj.Placement
        base = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
                if not obj.Base.Shape.isValid():
                    if not obj.Base.Shape.Solids:
                        # let pass invalid objects if they have solids...
                        return
                if hasattr(obj, "Tool"):
                    if obj.Tool:
                        try:
                            base = obj.Tool.Shape.copy().makePipe(
                                obj.Base.Shape.copy())
                        except Part.OCCError:
                            FreeCAD.Console.PrintError(
                                translate(
                                    "Arch",
                                    "Error: The base shape couldn't be extruded along this tool object"
                                ))
                            return
                if not base:
                    if not height:
                        return
                    if obj.Normal == Vector(0, 0, 0):
                        if len(obj.Base.Shape.Faces) > 0:
                            normal = obj.Base.Shape.Faces[0].normalAt(.5, .5)
                        else:
                            normal = DraftGeomUtils.getNormal(obj.Base.Shape)
                            if not normal:
                                normal = FreeCAD.Vector(0, 0, 1)
                            #p = FreeCAD.Placement(obj.Base.Placement)
                            #normal = p.Rotation.multVec(normal)
                    else:
                        normal = Vector(obj.Normal)
                    normal = normal.multiply(height)
                    base = obj.Base.Shape.copy()
                    if base.Solids:
                        pass
                    elif base.Faces:
                        base = base.extrude(normal)
                    elif (len(base.Wires) == 1):
                        if base.Wires[0].isClosed():
                            try:
                                base = Part.Face(base.Wires[0])
                                base = base.extrude(normal)
                            except Part.OCCError:
                                FreeCAD.Console.PrintError(
                                    obj.Label + " : " + str(
                                        translate(
                                            "Arch",
                                            "Unable to extrude the base shape\n"
                                        )))
                                return

            elif obj.Base.isDerivedFrom("Mesh::Feature"):
                if obj.Base.Mesh.isSolid():
                    if obj.Base.Mesh.countComponents() == 1:
                        sh = ArchCommands.getShapeFromMesh(obj.Base.Mesh)
                        if sh.isClosed() and sh.isValid() and sh.Solids and (
                                not sh.isNull()):
                            base = sh
                        else:
                            FreeCAD.Console.PrintWarning(
                                str(
                                    translate(
                                        "Arch",
                                        "This mesh is an invalid solid")))
                            obj.Base.ViewObject.show()
        else:
            base = self.getProfiles(obj)
            if base:
                if length > height:
                    normal = normal.multiply(length)
                else:
                    normal = normal.multiply(height)
                base = Part.Face(base[0])
                base = base.extrude(normal)

        base = self.processSubShapes(obj, base, pl)
        self.applyShape(obj, base, pl)
Ejemplo n.º 7
0
    def update(self):
        mode = self.imode
        print("focus", focus())
        ef = self.ef
        print("val,x,y,k", ef.mouseWheel, ef.posx, ef.posy, ef.key)
        #hilfsfenster
        hd = self.helperDok()

        # move-mode
        if mode == 0 or mode == -1:
            try:
                bb = App.activeDocument().BSpline
                pos = self.dial.value()

                try:
                    t = hd.Target.Shape.Vertex1.Point
                except:
                    t = FreeCAD.Vector()
                print("Target", t)
                pp = bb.Shape.Edge1.Curve.getPoles()
                points = pp
                if pos > 0:
                    pp2 = pp[:pos] + [t] + pp[pos + 1:]
                else:
                    pp2 = [t] + pp[pos + 1:]

                bs = bb.Shape.Edge1.Curve.copy()
                bs.setPole(pos + 1, FreeCAD.Vector(t))
                bb.Shape = bs.toShape()
                points = pp2

            except:
                print "ExCEPT - need to create helper BSpline"
                src = self.getsource()
                points = src.Shape.Edge1.Curve.getPoles()
                mybsc = App.activeDocument().addObject('Part::Feature',
                                                       'BSpline')
                mybsc.Shape = src.Shape
                mybsc.ViewObject.Selectable = False

                Gui.activeDocument().activeView().viewAxonometric()
                Gui.SendMsgToActiveView("ViewFit")
                bb = App.activeDocument().ActiveObject

            Gui.Selection.addSelection(bb)

            self.points = points
            self.setcursor()
            #reset diff
            self.ef.mouseWheel = 0
            self.settarget()
            return

        if mode == 1:
            bb = App.activeDocument().BSpline
            pos = self.dial.value()

            #			try:
            #				t=hd.Target.Shape.Point
            #			except:
            #				t=FreeCAD.Vector()

            t1 = hd.Target.Shape.Vertex1.Point
            t = hd.Target.Shape.Vertex2.Point
            t2 = hd.Target.Shape.Vertex3.Point

            pp = bb.Shape.Edge1.Curve.getPoles()
            points = pp
            [pi1, pi, pi2] = liposs(points, pos - 1, pos + 1)
            pp2 = pp
            pp2[pi1] = t1
            pp2[pi2] = t2
            pp2[pi] = t

            print("len pp, pp2", len(pp), len(pp2))

            bs = bb.Shape.Edge1.Curve.copy()
            bs.setPole(pi1 + 1, FreeCAD.Vector(t1))
            bs.setPole(pi + 1, FreeCAD.Vector(t))
            bs.setPole(pi2 + 1, FreeCAD.Vector(t2))

            bb = hd.TargetCurve
            bb.Shape = bs.toShape()
            points = pp2

            Gui.Selection.addSelection(bb)

            self.points = points
            self.setcursor()
            #reset diff
            self.ef.mouseWheel = 0
            self.settarget()
            return

#-----------------------
        elif mode == 2:
            faktor = self.dials.value()
            self.dials.setValue(0)

            print("sharpen.", faktor)
            pos = self.dial.value()
            dok = self.helperDok()

            pp = self.points

            t1 = pp[pos - 1] * (1 - 0.01 * faktor) + pp[pos] * 0.01 * faktor
            if pos == len(pp) - 1:
                t2 = pp[0] * (1 - 0.01 * faktor) + pp[pos] * 0.01 * faktor
            else:
                t2 = pp[pos + 1] * (1 -
                                    0.01 * faktor) + pp[pos] * 0.01 * faktor

            if pos == len(pp) - 1:
                pp2 = pp[1:pos - 1] + [t1, pp[pos], t2]  # +pp[pos+2:]
            elif pos > 0:
                pp2 = pp[:pos - 1] + [t1, pp[pos], t2] + pp[pos + 2:]
            else:
                pp2 = [t1, pp[pos], t2] + pp[2:-1]

            bb = dok.TargetCurve

            # bspline curve
            bs = dok.BSpline.Shape.Edge1.Curve.copy()
            if pos == 0: posa = len(pp)
            else: posa = pos
            bs.setPole(posa, FreeCAD.Vector(t1))
            if pos == len(pp) - 1: posb = 1
            else: posb = pos + 2

            bs.setPole(posb, FreeCAD.Vector(t2))
            dok.BSpline.Shape = bs.toShape()

            pol = Part.makePolygon(pp2 + [pp2[0]])
            bb.Shape = Part.Compound([pol])

            points = pp2

        elif mode == 4:
            print "rotate NEIOGHJHGJH"

#-----------------------
        elif mode == 3:
            # colinear neighbors
            faktor = self.dials.value()
            #faktor= 100
            self.dials.setValue(0)

            print("update sharpen.", faktor)
            pos = self.dial.value()
            dok = self.helperDok()

            pp = self.points

            if pos == len(pp) - 1:
                t2 = pp[pos] + (pp[0] - pp[pos - 1]) * (1 - 0.01 * faktor)
                t1 = pp[pos] - (pp[0] - pp[pos - 1]) * (1 - 0.01 * faktor)
            else:
                t2 = pp[pos] + (pp[pos + 1] - pp[pos - 1]) * (1 -
                                                              0.01 * faktor)
                t1 = pp[pos] - (pp[pos + 1] - pp[pos - 1]) * (1 -
                                                              0.01 * faktor)

#			if pos==len(pp)-1:
#				t2=pp[0]*(1-0.01*faktor)+pp[pos]*0.01*faktor
#			else:
#				t2=pp[pos]+(pp[pos+1]-pp[pos-1])*(1-0.01*faktor)
#				t1=pp[pos]-(pp[pos+1]-pp[pos-1])*(1-0.01*faktor)

            if pos == len(pp) - 1:
                pp2 = pp[1:pos - 1] + [t1, pp[pos], t2]  # +pp[pos+2:]
            elif pos > 0:
                pp2 = pp[:pos - 1] + [t1, pp[pos], t2] + pp[pos + 2:]
            else:
                pp2 = [t1, pp[pos], t2] + pp[2:-1]

            bb = dok.TargetCurve

            # bspline curve
            bs = dok.BSpline.Shape.Edge1.Curve.copy()
            if pos == 0: posa = len(pp)
            else: posa = pos
            bs.setPole(posa, FreeCAD.Vector(t1))
            if pos == len(pp) - 1: posb = 1
            else: posb = pos + 2

            bs.setPole(posb, FreeCAD.Vector(t2))
            dok.BSpline.Shape = bs.toShape()

            pol = Part.makePolygon(pp2 + [pp2[0]])
            bb.Shape = Part.Compound([pol])

            points = pp2

            #----------------------

            Gui.Selection.addSelection(bb)

            self.points = points
            self.setcursor()
            #reset diff
            self.ef.mouseWheel = 0
            self.settarget()
            return

        else:
            print "!!!!!!!!!!!!!! no imp for this mode!!"
Ejemplo n.º 8
0
def getCutVolume(cutplane, shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    import Part
    placement = FreeCAD.Placement(cutplane.Placement)
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    um = vm = wm = 0
    ax = placement.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    u = placement.Rotation.multVec(FreeCAD.Vector(1, 0, 0))
    v = placement.Rotation.multVec(FreeCAD.Vector(0, 1, 0))
    if not bb.isCutPlane(placement.Base, ax):
        FreeCAD.Console.PrintMessage(
            str(translate("Arch", "No objects are cut by the plane")))
        return None, None, None
    else:
        corners = [
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMax)
        ]
        for c in corners:
            dv = c.sub(placement.Base)
            um1 = DraftVecUtils.project(dv, u).Length
            um = max(um, um1)
            vm1 = DraftVecUtils.project(dv, v).Length
            vm = max(vm, vm1)
            wm1 = DraftVecUtils.project(dv, ax).Length
            wm = max(wm, wm1)
        p1 = FreeCAD.Vector(-um, vm, 0)
        p2 = FreeCAD.Vector(um, vm, 0)
        p3 = FreeCAD.Vector(um, -vm, 0)
        p4 = FreeCAD.Vector(-um, -vm, 0)
        cutface = Part.makePolygon([p1, p2, p3, p4, p1])
        cutface = Part.Face(cutface)
        cutface.Placement = placement
        cutnormal = DraftVecUtils.scaleTo(ax, wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = DraftVecUtils.neg(cutnormal)
        invcutvolume = cutface.extrude(cutnormal)
        return cutface, cutvolume, invcutvolume
Ejemplo n.º 9
0
    def computeAreas(self,obj):

        if not obj.Shape:
            return
        if obj.Shape.isNull():
            return
        if not obj.Shape.isValid():
            return
        if not obj.Shape.Faces:
            return
        if not hasattr(obj,"Perimeter"): # check we have a latest version site
            return
        if not obj.Terrain:
            return
        # compute area
        fset = []
        for f in obj.Shape.Faces:
            if f.normalAt(0,0).getAngle(FreeCAD.Vector(0,0,1)) < 1.5707:
                fset.append(f)
        if fset:
            import Drawing,Part
            pset = []
            for f in fset:
                try:
                    pf = Part.Face(Part.Wire(Drawing.project(f,FreeCAD.Vector(0,0,1))[0].Edges))
                except Part.OCCError:
                    # error in computing the area. Better set it to zero than show a wrong value
                    if obj.ProjectedArea.Value != 0:
                        print("Error computing areas for ",obj.Label)
                        obj.ProjectedArea = 0
                else:
                    pset.append(pf)
            if pset:
                self.flatarea = pset.pop()
                for f in pset:
                    self.flatarea = self.flatarea.fuse(f)
                self.flatarea = self.flatarea.removeSplitter()
                if obj.ProjectedArea.Value != self.flatarea.Area:
                    obj.ProjectedArea = self.flatarea.Area
        # compute perimeter
        lut = {}
        for e in obj.Shape.Edges:
            lut.setdefault(e.hashCode(),[]).append(e)
        l = 0
        for e in lut.values():
            if len(e) == 1: # keep only border edges
                l += e[0].Length
        if l:
                if obj.Perimeter.Value != l:
                    obj.Perimeter = l
        # compute volumes
        if obj.Terrain.Shape.Solids:
            shapesolid = obj.Terrain.Shape.copy()
        else:
            shapesolid = obj.Terrain.Shape.extrude(obj.ExtrusionVector)
        addvol = 0
        subvol = 0
        for sub in obj.Subtractions:
            subvol += sub.Shape.common(shapesolid).Volume
        for sub in obj.Additions:
            addvol += sub.Shape.cut(shapesolid).Volume
        if obj.SubtractionVolume.Value != subvol:
            obj.SubtractionVolume = subvol
        if obj.AdditionVolume.Value != addvol:
            obj.AdditionVolume = addvol
Ejemplo n.º 10
0
    def execute(self, obj):
        PathLog.track()
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        toolLoad = obj.ToolController
        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError(
                "No Tool Controller is selected. We need a tool to build a Path."
            )
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(toolLoad)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError(
                    "No Tool found or diameter is zero. We need a tool to build a Path."
                )
                return
            else:
                self.radius = tool.Diameter / 2

        if not obj.Base:
            parentJob = PathUtils.findParentJob(obj)
            if parentJob is None:
                return
            baseobject = parentJob.Base
            if baseobject is None:
                return
            holes = self.findHoles(obj, baseobject.Shape)
            for hole in holes:
                self.addDrillableLocation(obj, baseobject, hole[0])

        locations = []
        output = "(Begin Drilling)\n"
        if obj.Base:
            for loc in obj.Base:
                #print loc
                for sub in loc[1]:
                    #locations.append(self._findDrillingVector(loc))

                    if "Face" in sub or "Edge" in sub:
                        s = getattr(loc[0].Shape, sub)
                    else:
                        s = loc[0].Shape

                    if s.ShapeType in ['Wire', 'Edge']:
                        X = s.Edges[0].Curve.Center.x
                        Y = s.Edges[0].Curve.Center.y
                        Z = s.Edges[0].Curve.Center.z
                    elif s.ShapeType in ['Vertex']:
                        X = s.Point.x
                        Y = s.Point.y
                        Z = s.Point.z
                    elif s.ShapeType in ['Face']:
                        #if abs(s.normalAt(0, 0).z) == 1:  # horizontal face
                        X = s.CenterOfMass.x
                        Y = s.CenterOfMass.y
                        Z = s.CenterOfMass.z
                    locations.append(FreeCAD.Vector(X, Y, Z))

            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:
            p0 = locations[0]
            output += "G0 X" + fmt(p0.x) + " Y" + fmt(
                p0.y) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p.x) + \
                    " Y" + fmt(p.y) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
Ejemplo n.º 11
0
    def generateConstraintAreas(self, doc, layerNumber, grp, layerName,
                                layerColor, layerTransparent):
        typeL = PCBconf.softLayers[self.databaseType][layerNumber]['ltype']

        for i in self.wersjaFormatu.getConstraintAreas(layerNumber):
            ser = doc.addObject('Sketcher::SketchObject',
                                "Sketch_{0}".format(layerName))
            ser.ViewObject.Visibility = False
            #
            if i[0] == 'rect':
                try:
                    height = i[5]
                except:
                    height = 0

                x1 = i[1]
                y1 = i[2]

                x2 = i[3]
                y2 = i[2]

                x3 = i[3]
                y3 = i[4]

                x4 = i[1]
                y4 = i[4]

                try:
                    if i[6] != 0:
                        xs = (i[1] + i[3]) / 2.
                        ys = (i[2] + i[4]) / 2.

                        mat = mathFunctions()
                        (x1, y1) = mat.obrocPunkt2([x1, y1], [xs, ys], i[6])
                        (x2, y2) = mat.obrocPunkt2([x2, y2], [xs, ys], i[6])
                        (x3, y3) = mat.obrocPunkt2([x3, y3], [xs, ys], i[6])
                        (x4, y4) = mat.obrocPunkt2([x4, y4], [xs, ys], i[6])
                except:
                    pass

                ser.addGeometry(
                    Part.LineSegment(FreeCAD.Vector(x1, y1, 0),
                                     FreeCAD.Vector(x2, y2, 0)))
                ser.addGeometry(
                    Part.LineSegment(FreeCAD.Vector(x2, y2, 0),
                                     FreeCAD.Vector(x3, y3, 0)))
                ser.addGeometry(
                    Part.LineSegment(FreeCAD.Vector(x3, y3, 0),
                                     FreeCAD.Vector(x4, y4, 0)))
                ser.addGeometry(
                    Part.LineSegment(FreeCAD.Vector(x4, y4, 0),
                                     FreeCAD.Vector(x1, y1, 0)))
            elif i[0] == 'circle':
                try:
                    try:
                        height = i[5]
                    except:
                        height = 0

                    if i[4] == 0:
                        ser.addGeometry(
                            Part.Circle(FreeCAD.Vector(i[1], i[2], 0),
                                        FreeCAD.Vector(0, 0, 1), i[3]), False)
                    else:
                        ser.addGeometry(
                            Part.Circle(FreeCAD.Vector(i[1], i[2], 0),
                                        FreeCAD.Vector(0, 0, 1),
                                        i[3] + i[4] / 2))
                        ser.addGeometry(
                            Part.Circle(FreeCAD.Vector(i[1], i[2], 0),
                                        FreeCAD.Vector(0, 0, 1),
                                        i[3] - i[4] / 2))
                except Exception as e:
                    FreeCAD.Console.PrintWarning("3. {0}\n".format(e))
            elif i[0] == 'polygon':
                try:
                    height = i[2]
                except:
                    height = 0

                for j in i[1]:
                    if j[0] == 'Line':
                        ser.addGeometry(
                            Part.LineSegment(FreeCAD.Vector(j[1], j[2], 0),
                                             FreeCAD.Vector(j[3], j[4], 0)))
                    elif j[0] == 'Arc3P':
                        x1 = j[1]
                        y1 = j[2]
                        x2 = j[3]
                        y2 = j[4]
                        [x3, y3] = self.arcMidPoint([x2, y2], [x1, y1], j[5])

                        arc = Part.ArcOfCircle(FreeCAD.Vector(x1, y1, 0.0),
                                               FreeCAD.Vector(x3, y3, 0.0),
                                               FreeCAD.Vector(x2, y2, 0.0))
                        ser.addGeometry(arc)
            #
            #FreeCAD.ActiveDocument.recompute()
            ser.recompute()
            createConstraintArea(ser, typeL, height)
            self.updateView()
Ejemplo n.º 12
0
    def startElement(self, tag, attributes):

        if tag == "wall":
            name = attributes["id"]
            p1 = FreeCAD.Vector(
                float(attributes["xStart"]) * 10,
                float(attributes["yStart"]) * 10, 0)
            p2 = FreeCAD.Vector(
                float(attributes["xEnd"]) * 10,
                float(attributes["yEnd"]) * 10, 0)
            height = float(attributes["height"]) * 10
            thickness = float(attributes["thickness"]) * 10
            if DEBUG: print "Creating wall: ", name
            line = Draft.makeLine(p1, p2)
            if self.makeIndividualWalls:
                wall = Arch.makeWall(baseobj=line,
                                     width=thickness,
                                     height=height,
                                     name=name)
                wall.Label = name
            else:
                self.lines.setdefault(str(thickness) + ";" + str(height),
                                      []).append(line)

        elif tag == "pieceOfFurniture":
            name = attributes["name"]
            data = self.z.read(attributes["model"])
            th, tf = tempfile.mkstemp(suffix=".obj")
            f = pyopen(tf, "wb")
            f.write(data)
            f.close()
            os.close(th)
            m = Mesh.read(tf)
            fx = (float(attributes["width"]) / 100) / m.BoundBox.XLength
            fy = (float(attributes["height"]) / 100) / m.BoundBox.YLength
            fz = (float(attributes["depth"]) / 100) / m.BoundBox.ZLength
            mat = FreeCAD.Matrix()
            mat.scale(1000 * fx, 1000 * fy, 1000 * fz)
            mat.rotateX(math.pi / 2)
            mat.rotateZ(math.pi)
            if DEBUG: print "Creating furniture: ", name
            if "angle" in attributes.keys():
                mat.rotateZ(float(attributes["angle"]))
            m.transform(mat)
            os.remove(tf)
            p = m.BoundBox.Center.negative()
            p = p.add(
                FreeCAD.Vector(
                    float(attributes["x"]) * 10,
                    float(attributes["y"]) * 10, 0))
            p = p.add(
                FreeCAD.Vector(0, 0, m.BoundBox.Center.z - m.BoundBox.ZMin))
            m.Placement.Base = p
            obj = FreeCAD.ActiveDocument.addObject("Mesh::Feature", name)
            obj.Mesh = m
            self.furniture.append(obj)

        elif tag == "doorOrWindow":
            name = attributes["name"]
            data = self.z.read(attributes["model"])
            th, tf = tempfile.mkstemp(suffix=".obj")
            f = pyopen(tf, "wb")
            f.write(data)
            f.close()
            os.close(th)
            m = Mesh.read(tf)
            fx = (float(attributes["width"]) / 100) / m.BoundBox.XLength
            fy = (float(attributes["height"]) / 100) / m.BoundBox.YLength
            fz = (float(attributes["depth"]) / 100) / m.BoundBox.ZLength
            mat = FreeCAD.Matrix()
            mat.scale(1000 * fx, 1000 * fy, 1000 * fz)
            mat.rotateX(math.pi / 2)
            m.transform(mat)
            b = m.BoundBox
            v1 = FreeCAD.Vector(b.XMin, b.YMin - 500, b.ZMin)
            v2 = FreeCAD.Vector(b.XMax, b.YMin - 500, b.ZMin)
            v3 = FreeCAD.Vector(b.XMax, b.YMax + 500, b.ZMin)
            v4 = FreeCAD.Vector(b.XMin, b.YMax + 500, b.ZMin)
            sub = Part.makePolygon([v1, v2, v3, v4, v1])
            sub = Part.Face(sub)
            sub = sub.extrude(FreeCAD.Vector(0, 0, b.ZLength))
            os.remove(tf)
            shape = Arch.getShapeFromMesh(m)
            if not shape:
                shape = Part.Shape()
                shape.makeShapeFromMesh(m.Topology, 0.100000)
                shape = shape.removeSplitter()
            if shape:
                if DEBUG: print "Creating window: ", name
                if "angle" in attributes.keys():
                    shape.rotate(shape.BoundBox.Center,
                                 FreeCAD.Vector(0, 0, 1),
                                 math.degrees(float(attributes["angle"])))
                    sub.rotate(shape.BoundBox.Center, FreeCAD.Vector(0, 0, 1),
                               math.degrees(float(attributes["angle"])))
                p = shape.BoundBox.Center.negative()
                p = p.add(
                    FreeCAD.Vector(
                        float(attributes["x"]) * 10,
                        float(attributes["y"]) * 10, 0))
                p = p.add(
                    FreeCAD.Vector(
                        0, 0, shape.BoundBox.Center.z - shape.BoundBox.ZMin))
                if "elevation" in attributes.keys():
                    p = p.add(
                        FreeCAD.Vector(0, 0,
                                       float(attributes["elevation"]) * 10))
                shape.translate(p)
                sub.translate(p)
                obj = FreeCAD.ActiveDocument.addObject("Part::Feature",
                                                       name + "_body")
                obj.Shape = shape
                subobj = FreeCAD.ActiveDocument.addObject(
                    "Part::Feature", name + "_sub")
                subobj.Shape = sub
                if FreeCAD.GuiUp:
                    subobj.ViewObject.hide()
                win = Arch.makeWindow(baseobj=obj, name=name)
                win.Label = name
                win.Subvolume = subobj
                self.windows.append(win)
            else:
                print("importSH3D: Error creating shape for door/window " +
                      name)
Ejemplo n.º 13
0
    def getShape(self, obj):
        "computes a shape from a base shape and/or bounday faces"
        import Part
        shape = None
        faces = []

        pl = obj.Placement

        #print("starting compute")
        # 1: if we have a base shape, we use it

        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.Solids:
                    shape = obj.Base.Shape.copy()
                    shape = shape.removeSplitter()

        # 2: if not, add all bounding boxes of considered objects and build a first shape
        if shape:
            #print("got shape from base object")
            bb = shape.BoundBox
        else:
            bb = None
            for b in obj.Boundaries:
                if b[0].isDerivedFrom("Part::Feature"):
                    if not bb:
                        bb = b[0].Shape.BoundBox
                    else:
                        bb.add(b[0].Shape.BoundBox)
            if not bb:
                return
            shape = Part.makeBox(bb.XLength, bb.YLength, bb.ZLength,
                                 FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin))
            #print("created shape from boundbox")

        # 3: identifying boundary faces
        goodfaces = []
        for b in obj.Boundaries:
            if b[0].isDerivedFrom("Part::Feature"):
                for sub in b[1]:
                    if "Face" in sub:
                        fn = int(sub[4:]) - 1
                        faces.append(b[0].Shape.Faces[fn])
                        #print("adding face ",fn," of object ",b[0].Name)

        #print("total: ", len(faces), " faces")

        # 4: get cutvolumes from faces
        cutvolumes = []
        for f in faces:
            f = f.copy()
            f.reverse()
            cutface, cutvolume, invcutvolume = ArchCommands.getCutVolume(
                f, shape)
            if cutvolume:
                #print("generated 1 cutvolume")
                cutvolumes.append(cutvolume.copy())
                #Part.show(cutvolume)
        for v in cutvolumes:
            #print("cutting")
            shape = shape.cut(v)

        # 5: get the final shape
        if shape:
            if shape.Solids:
                #print("setting objects shape")
                shape = shape.Solids[0]
                obj.Shape = shape
                pl = pl.multiply(obj.Placement)
                obj.Placement = pl
                if hasattr(obj.Area, "Value"):
                    a = self.getArea(obj)
                    if obj.Area.Value != a:
                        obj.Area = a
                return

        print("Arch: error computing space boundary")
Ejemplo n.º 14
0
def get_svg(obj,
            scale=1, linewidth=0.35, fontsize=12,
            fillstyle="shape color", direction=None, linestyle=None,
            color=None, linespacing=None, techdraw=False, rotation=0,
            fillspaces=False, override=True):
    """Return a string containing an SVG representation of the object.

    Paramaeters
    -----------
    scale: float, optional
        It defaults to 1.
        It allows scaling line widths down, so they are resolution-independent.

    linewidth: float, optional
        It defaults to 0.35.

    fontsize: float, optional
        It defaults to 12, which is interpreted as `pt` unit (points).
        It is used if the given object contains any text.

    fillstyle: str, optional
        It defaults to 'shape color'.

    direction: Base::Vector3, optional
        It defaults to `None`.
        It is an arbitrary projection vector or a `WorkingPlane.Plane`
        instance.

    linestyle: optional
        It defaults to `None`.

    color: optional
        It defaults to `None`.

    linespacing: float, optional
        It defaults to `None`.

    techdraw: bool, optional
        It defaults to `False`.
        If it is `True`, it sets some options for generating SVG strings
        for displaying inside TechDraw.

    rotation: float, optional
        It defaults to 0.

    fillspaces: bool, optional
        It defaults to `False`.

    override: bool, optional
        It defaults to `True`.
    """
    # If this is a group, recursively call this function to gather
    # all the SVG strings from the contents of the group
    if hasattr(obj, "isDerivedFrom"):
        if (obj.isDerivedFrom("App::DocumentObjectGroup")
                or utils.get_type(obj) == "Layer"):
            svg = ""
            for child in obj.Group:
                svg += get_svg(child,
                               scale, linewidth, fontsize,
                               fillstyle, direction, linestyle,
                               color, linespacing, techdraw,
                               rotation, fillspaces, override)
            return svg

    pathdata = []
    svg = ""
    linewidth = float(linewidth)/scale
    if not override:
        if hasattr(obj, "ViewObject") and hasattr(obj.ViewObject, "LineWidth"):
            if hasattr(obj.ViewObject.LineWidth, "Value"):
                lw = obj.ViewObject.LineWidth.Value
            else:
                lw = obj.ViewObject.LineWidth
            linewidth = lw * linewidth

    fontsize = (float(fontsize)/scale)/2
    if linespacing:
        linespacing = float(linespacing)/scale
    else:
        linespacing = 0.5

    # print(obj.Label, "line spacing", linespacing, "scale", scale)

    # The number of times the dots are smaller than the arrow size
    pointratio = 0.75
    plane = None

    if direction:
        if isinstance(direction, App.Vector):
            if direction != App.Vector(0, 0, 0):
                plane = WorkingPlane.plane()
                plane.alignToPointAndAxis_SVG(App.Vector(0, 0, 0),
                                              direction.negative().negative(),
                                              0)
            else:
                raise ValueError("'direction' cannot be: Vector(0, 0, 0)")
        elif isinstance(direction, WorkingPlane.plane):
            plane = direction

    stroke = "#000000"
    if color and override:
        if "#" in color:
            stroke = color
        else:
            stroke = utils.get_rgb(color)
    elif App.GuiUp:
        # find print color
        pc = get_print_color(obj)
        if pc:
            stroke = utils.get_rgb(pc)
        # get line color
        elif hasattr(obj, "ViewObject"):
            if hasattr(obj.ViewObject, "LineColor"):
                stroke = utils.get_rgb(obj.ViewObject.LineColor)
            elif hasattr(obj.ViewObject, "TextColor"):
                stroke = utils.get_rgb(obj.ViewObject.TextColor)

    lstyle = "none"
    if override:
        lstyle = get_line_style(linestyle, scale)
    else:
        if hasattr(obj, "ViewObject") and hasattr(obj.ViewObject, "DrawStyle"):
            lstyle = get_line_style(obj.ViewObject.DrawStyle, scale)

    if not obj:
        pass

    elif isinstance(obj, Part.Shape):
        svg = _svg_shape(svg, obj, plane,
                         fillstyle, pathdata, stroke, linewidth, lstyle)

    elif utils.get_type(obj) in ["Dimension", "LinearDimension"]:
        svg = _svg_dimension(obj, plane, scale, linewidth, fontsize,
                             stroke, pointratio, techdraw, rotation)

    elif utils.get_type(obj) == "AngularDimension":
        if not App.GuiUp:
            _wrn("Export of dimensions to SVG is only available in GUI mode")

        if App.GuiUp:
            if obj.ViewObject.Proxy:
                if hasattr(obj.ViewObject.Proxy, "circle"):
                    prx = obj.ViewObject.Proxy

                    # drawing arc
                    fill = "none"
                    if obj.ViewObject.DisplayMode == "2D":
                        svg += get_path(obj, plane,
                                        fill, pathdata, stroke, linewidth,
                                        lstyle, fill_opacity=None,
                                        edges=[prx.circle])
                    else:
                        if hasattr(prx, "circle1"):
                            svg += get_path(obj, plane,
                                            fill, pathdata, stroke, linewidth,
                                            lstyle, fill_opacity=None,
                                            edges=[prx.circle1])
                            svg += get_path(obj, plane,
                                            fill, pathdata, stroke, linewidth,
                                            lstyle, fill_opacity=None,
                                            edges=[prx.circle2])
                        else:
                            svg += get_path(obj, plane,
                                            fill, pathdata, stroke, linewidth,
                                            lstyle, fill_opacity=None,
                                            edges=[prx.circle])

                    # drawing arrows
                    if hasattr(obj.ViewObject, "ArrowType"):
                        p2 = get_proj(prx.p2, plane)
                        p3 = get_proj(prx.p3, plane)
                        arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
                        arrowlength = 4*obj.ViewObject.ArrowSize.Value

                        _v1a = prx.circle.valueAt(prx.circle.FirstParameter
                                                  + arrowlength)
                        _v1b = prx.circle.valueAt(prx.circle.FirstParameter)

                        _v2a = prx.circle.valueAt(prx.circle.LastParameter
                                                  - arrowlength)
                        _v2b = prx.circle.valueAt(prx.circle.LastParameter)

                        u1 = get_proj(_v1a - _v1b, plane)
                        u2 = get_proj(_v2a - _v2b, plane)
                        angle1 = -DraftVecUtils.angle(u1)
                        angle2 = -DraftVecUtils.angle(u2)

                        if hasattr(obj.ViewObject, "FlipArrows"):
                            if obj.ViewObject.FlipArrows:
                                angle1 = angle1 + math.pi
                                angle2 = angle2 + math.pi

                        svg += get_arrow(obj,
                                         obj.ViewObject.ArrowType,
                                         p2, arrowsize, stroke, linewidth,
                                         angle1)
                        svg += get_arrow(obj,
                                         obj.ViewObject.ArrowType,
                                         p3, arrowsize, stroke, linewidth,
                                         angle2)

                    # drawing text
                    if obj.ViewObject.DisplayMode == "2D":
                        _diff = (prx.circle.LastParameter
                                 - prx.circle.FirstParameter)
                        t = prx.circle.tangentAt(prx.circle.FirstParameter
                                                 + _diff/2.0)
                        t = get_proj(t, plane)
                        tangle = DraftVecUtils.angle(t)
                        if (tangle <= -math.pi/2) or (tangle > math.pi/2):
                            tangle = tangle + math.pi

                        _diff = (prx.circle.LastParameter
                                 - prx.circle.FirstParameter)
                        _va = prx.circle.valueAt(prx.circle.FirstParameter
                                                 + _diff/2.0)
                        tbase = get_proj(_va, plane)

                        _v = App.Vector(0, 2.0/scale, 0)
                        tbase = tbase + DraftVecUtils.rotate(_v, tangle)
                        # print(tbase)
                    else:
                        tangle = 0
                        tbase = get_proj(prx.tbase, plane)

                    svg += svgtext.get_text(plane, techdraw,
                                            stroke, fontsize,
                                            obj.ViewObject.FontName,
                                            tangle, tbase, prx.string)

    elif utils.get_type(obj) == "Label":
        if getattr(obj.ViewObject, "Line", True):
            # Some Labels may have no Line property
            # Draw multisegment line
            proj_points = list(map(lambda x: get_proj(x, plane), obj.Points))
            path_dir_list = [format_point(proj_points[0], action='M')]
            path_dir_list += map(format_point, proj_points[1:])
            path_dir_str = " ".join(path_dir_list)

            svg_path = '<path '
            svg_path += 'fill="none" '
            svg_path += 'stroke="{}" '.format(stroke)
            svg_path += 'stroke-width="{}" '.format(linewidth)
            svg_path += 'd="{}"'.format(path_dir_str)
            svg_path += '/>'
            svg += svg_path

            # Draw arrow.
            # We are different here from 3D view
            # if Line is set to 'off', no arrow is drawn
            if hasattr(obj.ViewObject, "ArrowType") and len(obj.Points) >= 2:
                last_segment = App.Vector(obj.Points[-1] - obj.Points[-2])
                _v = get_proj(last_segment, plane)
                angle = -DraftVecUtils.angle(_v) + math.pi
                svg += get_arrow(obj,
                                 obj.ViewObject.ArrowType,
                                 proj_points[-1],
                                 obj.ViewObject.ArrowSize.Value/pointratio,
                                 stroke, linewidth, angle)

        if not App.GuiUp:
            _wrn("Export of texts to SVG is only available in GUI mode")

        # print text
        if App.GuiUp:
            fontname = obj.ViewObject.TextFont
            position = get_proj(obj.Placement.Base, plane)
            rotation = obj.Placement.Rotation
            justification = obj.ViewObject.TextAlignment
            text = obj.Text
            svg += svgtext.get_text(plane, techdraw,
                                    stroke, fontsize, fontname,
                                    rotation, position, text,
                                    linespacing, justification)

    elif utils.get_type(obj) in ["Annotation", "DraftText", "Text"]:
        # returns an svg representation of a document annotation
        if not App.GuiUp:
            _wrn("Export of texts to SVG is only available in GUI mode")

        if App.GuiUp:
            n = obj.ViewObject.FontName
            if utils.get_type(obj) == "Annotation":
                p = get_proj(obj.Position, plane)
                r = obj.ViewObject.Rotation.getValueAs("rad")
                t = obj.LabelText
            else:  # DraftText (old) or Text (new, 0.19)
                p = get_proj(obj.Placement.Base, plane)
                r = obj.Placement.Rotation
                t = obj.Text

            j = obj.ViewObject.Justification
            svg += svgtext.get_text(plane, techdraw,
                                    stroke, fontsize, n,
                                    r, p, t,
                                    linespacing, j)

    elif utils.get_type(obj) == "Axis":
        # returns the SVG representation of an Arch Axis system
        if not App.GuiUp:
            _wrn("Export of axes to SVG is only available in GUI mode")

        if App.GuiUp:
            vobj = obj.ViewObject
            lorig = lstyle
            fill = 'none'
            rad = vobj.BubbleSize.Value/2
            n = 0
            for e in obj.Shape.Edges:
                lstyle = lorig
                svg += get_path(obj, plane,
                                fill, pathdata, stroke, linewidth, lstyle,
                                fill_opacity=None,
                                edges=[e])
                lstyle = "none"
                pos = ["Start"]
                if hasattr(vobj, "BubblePosition"):
                    if vobj.BubblePosition == "Both":
                        pos = ["Start", "End"]
                    else:
                        pos = [vobj.BubblePosition]
                for p in pos:
                    if p == "Start":
                        p1 = e.Vertexes[0].Point
                        p2 = e.Vertexes[1].Point
                    else:
                        p1 = e.Vertexes[1].Point
                        p2 = e.Vertexes[0].Point
                    dv = p2.sub(p1)
                    dv.normalize()
                    center = p2.add(dv.scale(rad, rad, rad))
                    svg += get_circle(plane,
                                      fill, stroke, linewidth, lstyle,
                                      Part.makeCircle(rad, center))
                    if (hasattr(vobj.Proxy, "bubbletexts")
                            and len(vobj.Proxy.bubbletexts) >= n):
                        bubb = vobj.Proxy.bubbletexts
                        svg += '<text '
                        svg += 'fill="{}" '.format(stroke)
                        svg += 'font-size="{}" '.format(rad)
                        svg += 'style="text-anchor:middle;'
                        svg += 'text-align:center;'
                        svg += 'font-family: sans;" '
                        svg += 'transform="'
                        svg += 'translate({},{}) '.format(center.x + rad/4.0,
                                                          center.y - rad/3.0)
                        svg += 'scale(1,-1)"> '
                        svg += '<tspan>'
                        svg += bubb[n].string.getValues()[0]
                        svg += '</tspan>\n'
                        svg += '</text>\n'
                        n += 1
            lstyle = lorig

    elif utils.get_type(obj) == "Pipe":
        fill = stroke
        if obj.Base and obj.Diameter:
            svg += get_path(obj, plane,
                            fill, pathdata, stroke, linewidth, lstyle,
                            fill_opacity=None,
                            edges=obj.Base.Shape.Edges)
        for f in obj.Shape.Faces:
            if len(f.Edges) == 1:
                if isinstance(f.Edges[0].Curve, Part.Circle):
                    svg += get_circle(plane,
                                      fill, stroke, linewidth, lstyle,
                                      f.Edges[0])

    elif utils.get_type(obj) == "Rebar":
        fill = "none"
        basewire = obj.Base.Shape.Wires[0].copy()
        # Not applying rounding because the results are not correct
        # if hasattr(obj, "Rounding") and obj.Rounding:
        #     basewire = DraftGeomUtils.filletWire(
        #         basewire, obj.Rounding * obj.Diameter.Value
        #     )
        wires = []
        for placement in obj.PlacementList:
            wire = basewire.copy()
            wire.Placement = placement.multiply(basewire.Placement)
            wires.append(wire)
        svg += get_path(obj, plane,
                        fill, pathdata, stroke, linewidth, lstyle,
                        fill_opacity=None,
                        wires=wires)

    elif utils.get_type(obj) == "PipeConnector":
        pass

    elif utils.get_type(obj) == "Space":
        fill_opacity = 1

        # returns an SVG fragment for the text of a space
        if not App.GuiUp:
            _wrn("Export of spaces to SVG is only available in GUI mode")

        if App.GuiUp:
            vobj = obj.ViewObject
            if fillspaces and hasattr(obj, "Proxy"):
                if not hasattr(obj.Proxy, "face"):
                    obj.Proxy.getArea(obj, notouch=True)
                if hasattr(obj.Proxy, "face"):
                    # setting fill
                    if App.GuiUp:
                        fill = utils.get_rgb(vobj.ShapeColor,
                                             testbw=False)
                        fill_opacity = 1 - vobj.Transparency / 100.0
                    else:
                        fill = "#888888"
                    svg += get_path(obj, plane,
                                    fill, pathdata, stroke, linewidth,
                                    lstyle, fill_opacity=fill_opacity,
                                    wires=[obj.Proxy.face.OuterWire])
            c = utils.get_rgb(vobj.TextColor)
            n = vobj.FontName
            a = 0
            if rotation != 0:
                a = math.radians(rotation)

            t1 = vobj.Proxy.text1.string.getValues()
            t2 = vobj.Proxy.text2.string.getValues()
            scale = vobj.FirstLine.Value/vobj.FontSize.Value
            f1 = fontsize * scale

            if round(plane.axis.getAngle(App.Vector(0,0,1)),2) not in [0,3.14]:
                # if not in XY view, place the label at center
                p2 = obj.Shape.CenterOfMass
            else:
                _v = vobj.Proxy.coords.translation.getValue().getValue()
                p2 = obj.Placement.multVec(App.Vector(_v))

            _h = vobj.Proxy.header.translation.getValue().getValue()
            lspc = App.Vector(_h)
            p1 = p2 + lspc
            j = vobj.TextAlign
            t3 = svgtext.get_text(plane, techdraw,
                                  c, f1, n,
                                  a, get_proj(p1, plane), t1,
                                  linespacing, j, flip=True)
            svg += t3
            if t2:
                ofs = App.Vector(0, -lspc.Length, 0)
                if a:
                    Z = App.Vector(0, 0, 1)
                    ofs = App.Rotation(Z, -rotation).multVec(ofs)
                t4 = svgtext.get_text(plane, techdraw,
                                      c, fontsize, n,
                                      a, get_proj(p1, plane).add(ofs), t2,
                                      linespacing, j, flip=True)
                svg += t4

    elif hasattr(obj, 'Shape'):
        # In the past we tested for a Part Feature
        # elif obj.isDerivedFrom('Part::Feature'):
        #
        # however, this doesn't work for App::Links; instead we
        # test for a 'Shape'. All Part::Features should have a Shape,
        # and App::Links can have one as well.
        if obj.Shape.isNull():
            return ''

        fill_opacity = 1
        # setting fill
        if obj.Shape.Faces:
            if App.GuiUp:
                try:
                    m = obj.ViewObject.DisplayMode
                except AttributeError:
                    m = None

                vobj = obj.ViewObject
                if m != "Wireframe":
                    if fillstyle == "shape color":
                        fill = utils.get_rgb(vobj.ShapeColor,
                                             testbw=False)
                        fill_opacity = 1 - vobj.Transparency / 100.0
                    elif fillstyle in ("none",None):
                        fill = "none"
                    else:
                        fill = 'url(#'+fillstyle+')'
                        svg += get_pattern(fillstyle)
                else:
                    fill = "none"
            else:
                fill = "#888888"
        else:
            fill = 'none'

        if len(obj.Shape.Vertexes) > 1:
            wiredEdges = []
            if obj.Shape.Faces:
                for i, f in enumerate(obj.Shape.Faces):
                    # place outer wire first
                    wires = [f.OuterWire]
                    wires.extend([w for w in f.Wires if w.hashCode() != f.OuterWire.hashCode()])
                    svg += get_path(obj, plane,
                                    fill, pathdata, stroke, linewidth, lstyle,
                                    fill_opacity=fill_opacity,
                                    wires=f.Wires,
                                    pathname='%s_f%04d' % (obj.Name, i))
                    wiredEdges.extend(f.Edges)
            else:
                for i, w in enumerate(obj.Shape.Wires):
                    svg += get_path(obj, plane,
                                    fill, pathdata, stroke, linewidth, lstyle,
                                    fill_opacity=fill_opacity,
                                    edges=w.Edges,
                                    pathname='%s_w%04d' % (obj.Name, i))
                    wiredEdges.extend(w.Edges)
            if len(wiredEdges) != len(obj.Shape.Edges):
                for i, e in enumerate(obj.Shape.Edges):
                    if DraftGeomUtils.findEdge(e, wiredEdges) is None:
                        svg += get_path(obj, plane,
                                        fill, pathdata, stroke, linewidth,
                                        lstyle, fill_opacity=fill_opacity,
                                        edges=[e],
                                        pathname='%s_nwe%04d' % (obj.Name, i))
        else:
            # closed circle or spline
            if obj.Shape.Edges:
                if isinstance(obj.Shape.Edges[0].Curve, Part.Circle):
                    svg = get_circle(plane,
                                     fill, stroke, linewidth, lstyle,
                                     obj.Shape.Edges[0])
                else:
                    svg = get_path(obj, plane,
                                   fill, pathdata, stroke, linewidth, lstyle,
                                   fill_opacity=fill_opacity,
                                   edges=obj.Shape.Edges)

        if (App.GuiUp
                and hasattr(obj.ViewObject, "EndArrow")
                and obj.ViewObject.EndArrow
                and hasattr(obj.ViewObject, "ArrowType")
                and len(obj.Shape.Vertexes) > 1):
            p1 = get_proj(obj.Shape.Vertexes[-1].Point, plane)
            p2 = get_proj(obj.Shape.Vertexes[-2].Point, plane)
            angle = -DraftVecUtils.angle(p2 - p1)

            arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
            svg += get_arrow(obj,
                             obj.ViewObject.ArrowType,
                             p1, arrowsize, stroke, linewidth, angle)

    # techdraw expects bottom-to-top coordinates
    if techdraw:
        svg = '<g transform ="scale(1,-1)">\n    ' + svg + '</g>\n'

    return svg
Ejemplo n.º 15
0
    def draw(self):

        #helper Variables

        #Make the coresponding xRodClamp
        try:
            Gui.getDocument(self.name)
            Gui.getDocument(self.name).resetEdit()
            App.getDocument(self.name).recompute()
            App.closeDocument(self.name)
            App.setActiveDocument("")
            App.ActiveDocument = None
            Gui.ActiveDocument = None
        except:
            pass

        #make document
        App.newDocument(self.name)
        App.setActiveDocument(self.name)
        App.ActiveDocument = App.getDocument(self.name)
        Gui.ActiveDocument = Gui.getDocument(self.name)
        App.ActiveDocument = App.getDocument(self.name)

        #Make clamp body
        #Sketch points
        p1x = -gv.zEndstopSupportWidth / 2
        p1y = 0
        p2x = -gv.zEndstopSupportWidth / 2
        p2y = gv.zEndStopClampLength
        p3x = gv.zEndstopSupportWidth / 2
        p3y = gv.zEndStopClampLength
        p4x = gv.zEndstopSupportWidth / 2
        p4y = p1y

        #Make Sketch
        App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch')
        App.activeDocument().Sketch.Placement = App.Placement(
            App.Vector(0.000000, 0.000000, 0.000000),
            App.Rotation(0.000000, 0.000000, 0.000000, 1.000000))
        #		Gui.activeDocument().activeView().setCamera('#Inventor V2.1 ascii \n OrthographicCamera {\n viewportMapping ADJUST_CAMERA \n position 0 0 87 \n orientation 0 0 1  0 \n nearDistance -112.88701 \n farDistance 287.28702 \n aspectRatio 1 \n focalDistance 87 \n height 143.52005 }')
        #		Gui.activeDocument().setEdit('Sketch')
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p4x, p4y, 0)))
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p3x, p3y, 0)))
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p2x, p2y, 0)))
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p1x, p1y, 0)))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 0, 2, 1, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 1, 2, 2, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 2, 2, 3, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 3, 2, 0, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Horizontal', 0))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Horizontal', 2))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Vertical', 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Vertical', 3))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Symmetric', 0, 2, 0, 1, -1, 1))
        App.ActiveDocument.recompute()

        #add dimensions
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('DistanceY', 1, gv.zEndStopClampLength))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('DistanceX', 2, -gv.zEndstopSupportWidth))
        App.ActiveDocument.recompute()
        #		Gui.getDocument(self.name).resetEdit()
        App.getDocument(self.name).recompute()

        #pad rod support
        App.activeDocument().addObject("PartDesign::Pad", "Pad")
        App.activeDocument().Pad.Sketch = App.activeDocument().Sketch
        App.activeDocument().Pad.Length = 10.0
        App.ActiveDocument.recompute()
        Gui.activeDocument().hide("Sketch")
        App.ActiveDocument.Pad.Length = gv.zRodDiaL / 2 + gv.zEndstopBodyThickness - gv.clampGap / 2
        App.ActiveDocument.Pad.Reversed = 0
        App.ActiveDocument.Pad.Midplane = 0
        App.ActiveDocument.Pad.Length2 = 100.000000
        App.ActiveDocument.Pad.Type = 0
        App.ActiveDocument.Pad.UpToFace = None
        App.ActiveDocument.recompute()
        #		Gui.activeDocument().resetEdit()

        #make cut out for rod
        #sketch points
        p1x = 0
        p1y = gv.zRodDiaL / 2 + gv.zEndstopBodyThickness

        #Make Sketch
        #make sketch
        App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch001')
        App.activeDocument().Sketch001.Support = uf.getFace(
            App.ActiveDocument.Pad, None, None, 0, 0, None, None)
        App.activeDocument().recompute()
        #		Gui.activeDocument().setEdit('Sketch001')
        App.ActiveDocument.Sketch001.addExternal(
            "Pad",
            uf.getEdge(
                App.ActiveDocument.Pad, 0, 0, 0, 0,
                gv.zRodDiaL / 2 + gv.zEndstopBodyThickness - gv.clampGap / 2,
                0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addGeometry(
            Part.Circle(App.Vector(p1x, p1y, 0), App.Vector(0, 0, 1),
                        gv.zRodDiaL / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('PointOnObject', 0, 3, -2))
        App.ActiveDocument.recompute()

        #add dimensions
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Distance', 0, 3, -3, gv.clampGap / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Radius', 0, gv.zRodDiaL / 2))
        App.ActiveDocument.recompute()
        Gui.getDocument(self.name).resetEdit()
        App.getDocument(self.name).recompute()

        #Cut through all
        App.activeDocument().addObject("PartDesign::Pocket", "Pocket")
        App.activeDocument().Pocket.Sketch = App.activeDocument().Sketch001
        App.activeDocument().Pocket.Length = 5.0
        App.ActiveDocument.recompute()
        Gui.activeDocument().hide("Sketch001")
        Gui.activeDocument().hide("Pad")
        Gui.ActiveDocument.Pocket.ShapeColor = Gui.ActiveDocument.Pad.ShapeColor
        Gui.ActiveDocument.Pocket.LineColor = Gui.ActiveDocument.Pad.LineColor
        Gui.ActiveDocument.Pocket.PointColor = Gui.ActiveDocument.Pad.PointColor
        App.ActiveDocument.Pocket.Length = 5.000000
        App.ActiveDocument.Pocket.Type = 1
        App.ActiveDocument.Pocket.UpToFace = None
        App.ActiveDocument.recompute()
        Gui.activeDocument().resetEdit()

        #cut Right clamp hole
        #Sketch points
        p1x = gv.zRodDiaL / 2 + gv.printedToPrintedDia / 2
        p1y = gv.printedToPrintedDia / 2 + gv.mountToPrintedPadding

        #Make Sketch
        App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch002')
        App.activeDocument().Sketch002.Support = uf.getFace(
            App.ActiveDocument.Pocket, 0, 1, None, None,
            gv.zRodDiaL / 2 + gv.zEndstopBodyThickness - gv.clampGap / 2, 0)
        App.activeDocument().recompute()
        App.activeDocument().recompute()
        #		Gui.activeDocument().setEdit('Sketch002')
        App.ActiveDocument.Sketch002.addExternal(
            "Pocket",
            uf.getEdge(
                App.ActiveDocument.Pocket, gv.zEndstopSupportWidth / 2, 0,
                gv.zEndStopClampLength / 2, 0,
                gv.zRodDiaL / 2 + gv.zEndstopBodyThickness - gv.clampGap / 2,
                0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Circle(App.Vector(p1x, p1y, 0), App.Vector(0, 0, 1),
                        gv.printedToPrintedDia / 2))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch002.addConstraint(Sketcher.Constraint('Distance',0,3,-3,p1y))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch002.addConstraint(Sketcher.Constraint('DistanceY',-1,1,0,3,p1y))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch002.addConstraint(Sketcher.Constraint('Radius',0,gv.printedToPrintedDia/2))
        App.ActiveDocument.recompute()
        Gui.getDocument(self.name).resetEdit()
        App.getDocument(self.name).recompute()

        #Cut clamp hole through all
        App.activeDocument().addObject("PartDesign::Pocket", "Pocket001")
        App.activeDocument().Pocket001.Sketch = App.activeDocument().Sketch002
        App.activeDocument().Pocket001.Length = 5.0
        App.ActiveDocument.recompute()
        Gui.activeDocument().hide("Sketch002")
        Gui.activeDocument().hide("Pocket")
        #		Gui.ActiveDocument.Pocket001.ShapeColor=Gui.ActiveDocument.Pocket.ShapeColor
        #		Gui.ActiveDocument.Pocket001.LineColor=Gui.ActiveDocument.Pocket.LineColor
        #		Gui.ActiveDocument.Pocket001.PointColor=Gui.ActiveDocument.Pocket.PointColor
        App.ActiveDocument.Pocket001.Length = 5.000000
        App.ActiveDocument.Pocket001.Type = 1
        App.ActiveDocument.Pocket001.UpToFace = None
        App.ActiveDocument.recompute()
        #		Gui.activeDocument().resetEdit()

        #Mirror clamp hole
        App.activeDocument().addObject("PartDesign::Mirrored", "Mirrored")
        App.ActiveDocument.recompute()
        App.activeDocument().Mirrored.Originals = [
            App.activeDocument().Pocket001,
        ]
        App.activeDocument().Mirrored.MirrorPlane = (
            App.activeDocument().Sketch002, ["V_Axis"])
        Gui.activeDocument().Pocket001.Visibility = False
        #		Gui.activeDocument().setEdit('Mirrored')
        #		Gui.ActiveDocument.Mirrored.ShapeColor=Gui.ActiveDocument.Pocket001.ShapeColor
        #		Gui.ActiveDocument.Mirrored.DisplayMode=Gui.ActiveDocument.Pocket001.DisplayMode
        App.ActiveDocument.Mirrored.Originals = [
            App.ActiveDocument.Pocket001,
        ]
        App.ActiveDocument.Mirrored.MirrorPlane = (
            App.ActiveDocument.Sketch002, ["V_Axis"])
        App.ActiveDocument.recompute()
        #		Gui.activeDocument().resetEdit()

        #Make channel for contact
        #Sketch Points
        p1x = -gv.zEndstopSupportWidth / 2
        p1y = -(2 * gv.mountToPrintedPadding + gv.printedToPrintedDia +
                2 * gv.xEndstopChannelWidth + gv.zEndstopJogWidth)
        p2x = p1x
        p2y = -(2 * gv.mountToPrintedPadding + gv.printedToPrintedDia +
                gv.zEndstopJogWidth)
        p3x = -gv.zEndstopJogWidth
        p3y = p2y
        p4x = 0
        p4y = -(2 * gv.mountToPrintedPadding + gv.printedToPrintedDia)
        p5x = -p3x
        p5y = p2y
        p6x = -p1x
        p6y = p2y
        p7x = p6x
        p7y = p1y
        p8x = p5x - (gv.xEndstopChannelWidth * math.tan(math.pi / 8))
        p8y = p1y
        p9x = p8x - math.pow(2, 0.5) * gv.xEndstopChannelWidth * math.tan(
            math.pi / 8)
        p9y = p1y + math.pow(2, 0.5) * gv.xEndstopChannelWidth * math.tan(
            math.pi / 8)
        p10x = p4x
        p10y = p1y + gv.zEndstopJogWidth - math.pow(
            2, 0.5) * gv.xEndstopChannelWidth * math.tan(math.pi / 8)
        p11x = p3x + (
            gv.xEndstopChannelWidth * math.tan(math.pi / 8)) + math.pow(
                2, 0.5) * gv.xEndstopChannelWidth * math.tan(math.pi / 8)
        p11y = p9y
        p12x = p3x + (gv.xEndstopChannelWidth * math.tan(math.pi / 8))
        p12y = p1y

        #Make Sketch
        App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch003')
        App.activeDocument().Sketch003.Support = uf.getFace(
            App.ActiveDocument.Mirrored, 0, 0, None, None, 0, 0)
        App.activeDocument().recompute()
        App.activeDocument().recompute()
        #		Gui.activeDocument().setEdit('Sketch003')
        App.ActiveDocument.Sketch003.addExternal(
            "Mirrored",
            uf.getEdge(App.ActiveDocument.Mirrored,
                       -gv.zEndstopSupportWidth / 2, 0,
                       gv.zEndStopClampLength / 2, 0, 0, 0))
        App.ActiveDocument.Sketch003.addExternal(
            "Mirrored",
            uf.getEdge(App.ActiveDocument.Mirrored,
                       gv.zEndstopSupportWidth / 2, 0,
                       gv.zEndStopClampLength / 2, 0, 0, 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0)))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('PointOnObject', 0, 1, -3))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Vertical', 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 0, 2, 1, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Horizontal', 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 1, 2, 2, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p5x, p5y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 2, 2, 3, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p5x, p5y, 0), App.Vector(p6x, p6y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 3, 2, 4, 1))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Horizontal', 4))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p6x, p6y, 0), App.Vector(p7x, p7y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 4, 2, 5, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('PointOnObject', 4, 2, -4))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p7x, p7y, 0), App.Vector(p8x, p8y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 5, 2, 6, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('PointOnObject', 5, 2, -4))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p8x, p8y, 0), App.Vector(p9x, p9y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 6, 2, 7, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p9x, p9y, 0), App.Vector(p10x, p10y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 7, 2, 8, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch003.addConstraint(Sketcher.Constraint('PointOnObject',8,2,-3))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch003.addConstraint(Sketcher.Constraint('Horizontal',8))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p10x, p10y, 0), App.Vector(p11x, p11y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 8, 2, 9, 1))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch003.addConstraint(Sketcher.Constraint('Vertical',9))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch003.addConstraint(Sketcher.Constraint('PointOnObject',3,2,-4))
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p11x, p11y, 0), App.Vector(p12x, p12y, 0)))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 9, 2, 10, 1))
        App.ActiveDocument.recompute()
        #		App.ActiveDocument.Sketch003.addConstraint(Sketcher.Constraint('PointOnObject',10,2,7))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p12x, p12y, 0), App.Vector(p1x, p1y, 0)))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p11x, p11y, 0)))
        App.ActiveDocument.Sketch003.addGeometry(
            Part.Line(App.Vector(p5x, p5y, 0), App.Vector(p9x, p9y, 0)))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 10, 2, 11, 1))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 11, 2, 0, 1))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Horizontal', 6))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Horizontal', 11))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('PointOnObject', 2, 2, -2))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('PointOnObject', 8, 2, -2))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Parallel', 9, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Parallel', 3, 8))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.toggleConstruction(13)
        App.ActiveDocument.Sketch003.toggleConstruction(12)
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Equal', 0, 12))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Equal', 12, 13))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Equal', 13, 5))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Perpendicular', 2, 3))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 12, 2, 9, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 12, 1, 1, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 3, 2, 13, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Coincident', 13, 2, 7, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Perpendicular', 12, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Perpendicular', 13, 3))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Parallel', 10, 9))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('Parallel', 7, 8))
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('PointOnObject', 6, 2, 11))

        #add dimensions
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('DistanceY', 5, -gv.xEndstopChannelWidth))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('DistanceY', 3, 2, 2, 2, gv.zEndstopJogWidth))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch003.addConstraint(
            Sketcher.Constraint('DistanceY', -1, 1, 2, 2, -9.963388))
        App.ActiveDocument.recompute()

        Gui.getDocument('zEndstop').resetEdit()
        App.getDocument('zEndstop').recompute()

        #Cut top channel
        App.activeDocument().addObject("PartDesign::Pocket", "Pocket002")
        App.activeDocument().Pocket002.Sketch = App.activeDocument().Sketch003
        App.activeDocument().Pocket002.Length = 5.0
        App.ActiveDocument.recompute()
        Gui.activeDocument().hide("Sketch003")
        Gui.activeDocument().hide("Mirrored")
        Gui.activeDocument().setEdit('Pocket002')
        Gui.ActiveDocument.Pocket002.ShapeColor = Gui.ActiveDocument.Mirrored.ShapeColor
        Gui.ActiveDocument.Pocket002.LineColor = Gui.ActiveDocument.Mirrored.LineColor
        Gui.ActiveDocument.Pocket002.PointColor = Gui.ActiveDocument.Mirrored.PointColor
        App.ActiveDocument.Pocket002.Length = 3.000000
        App.ActiveDocument.Pocket002.Type = 0
        App.ActiveDocument.Pocket002.UpToFace = None
        App.ActiveDocument.recompute()
        Gui.activeDocument().resetEdit()

        #Use a linear pattern to add other channel
        App.activeDocument().addObject("PartDesign::LinearPattern",
                                       "LinearPattern")
        App.ActiveDocument.recompute()
        App.activeDocument().LinearPattern.Originals = [
            App.activeDocument().Pocket002,
        ]
        App.activeDocument().LinearPattern.Direction = (
            App.activeDocument().Sketch003, ["H_Axis"])
        App.activeDocument().LinearPattern.Length = 100
        App.activeDocument().LinearPattern.Occurrences = 2
        Gui.activeDocument().Pocket002.Visibility = False
        Gui.activeDocument().setEdit('LinearPattern')
        Gui.ActiveDocument.LinearPattern.ShapeColor = Gui.ActiveDocument.Pocket002.ShapeColor
        Gui.ActiveDocument.LinearPattern.DisplayMode = Gui.ActiveDocument.Pocket002.DisplayMode
        App.ActiveDocument.LinearPattern.Originals = [
            App.ActiveDocument.Pocket002,
        ]
        App.ActiveDocument.LinearPattern.Direction = (
            App.ActiveDocument.Sketch003, ["V_Axis"])
        App.ActiveDocument.LinearPattern.Reversed = 1
        App.ActiveDocument.LinearPattern.Length = 3.500000
        App.ActiveDocument.LinearPattern.Occurrences = 2
        App.ActiveDocument.recompute()
        Gui.activeDocument().resetEdit()
Ejemplo n.º 16
0
def makeSolarDiagram(longitude,latitude,scale=1,complete=False):

    """makeSolarDiagram(longitude,latitude,[scale,complete]):
    returns a solar diagram as a pivy node. If complete is
    True, the 12 months are drawn"""

    from subprocess import call
    py3_failed = call(["python3", "-c", "import Pysolar"])

    if py3_failed:
        try:
            import Pysolar
        except:
            print("Pysolar is not installed. Unable to generate solar diagrams")
            return None
    else:
        from subprocess import check_output

    from pivy import coin

    if not scale:
        return None

    def toNode(shape):
        "builds a pivy node from a simple linear shape"
        from pivy import coin
        buf = shape.writeInventor(2,0.01)
        buf = buf.replace("\n","")
        pts = re.findall("point \[(.*?)\]",buf)[0]
        pts = pts.split(",")
        pc = []
        for p in pts:
            v = p.strip().split()
            pc.append([float(v[0]),float(v[1]),float(v[2])])
        coords = coin.SoCoordinate3()
        coords.point.setValues(0,len(pc),pc)
        line = coin.SoLineSet()
        line.numVertices.setValue(-1)
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(line)
        return item

    circles = []
    sunpaths = []
    hourpaths = []
    circlepos = []
    hourpos = []

    # build the base circle + number positions
    import Part
    for i in range(1,9):
        circles.append(Part.makeCircle(scale*(i/8.0)))
    for ad in range(0,360,15):
        a = math.radians(ad)
        p1 = FreeCAD.Vector(math.cos(a)*scale,math.sin(a)*scale,0)
        p2 = FreeCAD.Vector(math.cos(a)*scale*0.125,math.sin(a)*scale*0.125,0)
        p3 = FreeCAD.Vector(math.cos(a)*scale*1.08,math.sin(a)*scale*1.08,0)
        circles.append(Part.LineSegment(p1,p2).toShape())
        circlepos.append((ad,p3))

    # build the sun curves at solstices and equinoxe
    year = datetime.datetime.now().year
    hpts = [ [] for i in range(24) ]
    m = [(6,21),(7,21),(8,21),(9,21),(10,21),(11,21),(12,21)]
    if complete:
        m.extend([(1,21),(2,21),(3,21),(4,21),(5,21)])
    for i,d in enumerate(m):
        pts = []
        for h in range(24):
            if not py3_failed:
                dt = "datetime.datetime(%s, %s, %s, %s)" % (year, d[0], d[1], h)
                alt_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_altitude_fast(%s, %s, %s))'" % (latitude, longitude, dt)
                alt = math.radians(float(check_output(alt_call, shell=True).strip()))
                az_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_azimuth(%s, %s, %s))'" % (latitude, longitude, dt)
                az = float(re.search('.+$', check_output(az_call, shell=True)).group(0))
            else:
                dt = datetime.datetime(year,d[0],d[1],h)
                alt = math.radians(Pysolar.solar.GetAltitudeFast(latitude,longitude,dt))
                az = Pysolar.solar.GetAzimuth(latitude,longitude,dt)
            az = -90 + az # pysolar's zero is south
            if az < 0:
                az = 360 + az
            az = math.radians(az)
            zc = math.sin(alt)*scale
            ic = math.cos(alt)*scale
            xc = math.cos(az)*ic
            yc = math.sin(az)*ic
            p = FreeCAD.Vector(xc,yc,zc)
            pts.append(p)
            hpts[h].append(p)
            if i in [0,6]:
                ep = FreeCAD.Vector(p)
                ep.multiply(1.08)
                if ep.z >= 0:
                    if h == 12:
                        if i == 0:
                            h = "SUMMER"
                        else:
                            h = "WINTER"
                        if latitude < 0:
                            if h == "SUMMER":
                                h = "WINTER"
                            else:
                                h = "SUMMER"
                    hourpos.append((h,ep))
        if i < 7:
            sunpaths.append(Part.makePolygon(pts))
    for h in hpts:
        if complete:
            h.append(h[0])
        hourpaths.append(Part.makePolygon(h))

    # cut underground lines
    sz = 2.1*scale
    cube = Part.makeBox(sz,sz,sz)
    cube.translate(FreeCAD.Vector(-sz/2,-sz/2,-sz))
    sunpaths = [sp.cut(cube) for sp in sunpaths]
    hourpaths = [hp.cut(cube) for hp in hourpaths]

    # build nodes
    ts = 0.005*scale # text scale
    mastersep = coin.SoSeparator()
    circlesep = coin.SoSeparator()
    numsep = coin.SoSeparator()
    pathsep = coin.SoSeparator()
    hoursep = coin.SoSeparator()
    hournumsep = coin.SoSeparator()
    mastersep.addChild(circlesep)
    mastersep.addChild(numsep)
    mastersep.addChild(pathsep)
    mastersep.addChild(hoursep)
    for item in circles:
        circlesep.addChild(toNode(item))
    for item in sunpaths:
        for w in item.Edges:
            pathsep.addChild(toNode(w))
    for item in hourpaths:
        for w in item.Edges:
            hoursep.addChild(toNode(w))
    for p in circlepos:
        text = coin.SoText2()
        s = p[0]-90
        s = -s
        if s > 360:
            s = s - 360
        if s < 0:
            s = 360 + s
        if s == 0:
            s = "N"
        elif s == 90:
            s = "E"
        elif s == 180:
            s = "S"
        elif s == 270:
            s = "W"
        else:
            s = str(s)
        text.string = s
        text.justification = coin.SoText2.CENTER
        coords = coin.SoTransform()
        coords.translation.setValue([p[1].x,p[1].y,p[1].z])
        coords.scaleFactor.setValue([ts,ts,ts])
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(text)
        numsep.addChild(item)
    for p in hourpos:
        text = coin.SoText2()
        s = str(p[0])
        text.string = s
        text.justification = coin.SoText2.CENTER
        coords = coin.SoTransform()
        coords.translation.setValue([p[1].x,p[1].y,p[1].z])
        coords.scaleFactor.setValue([ts,ts,ts])
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(text)
        numsep.addChild(item)
    return mastersep
Ejemplo n.º 17
0
    def test02(self):
        '''Verify bones are correctly generated for a Profile.'''
        doc = FreeCAD.newDocument("TestDressupDogbone")

        # This is a real world test to make sure none of the tool chain broke
        box0 = doc.addObject('Part::Box', 'Box')
        box0.Width = 100
        box0.Length = 100
        box0.Height = 10
        box1 = doc.addObject('Part::Box', 'Box')
        box1.Width = 50
        box1.Length = 50
        box1.Height = 20
        box1.Placement = FreeCAD.Placement(
            FreeCAD.Vector(25, 25, -5),
            FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0))
        doc.recompute()
        cut = doc.addObject('Part::Cut', 'Cut')
        cut.Base = box0
        cut.Tool = box1
        doc.recompute()

        for i in range(11):
            face = "Face%d" % (i + 1)
            f = cut.Shape.getElement(face)
            if f.Surface.Axis == FreeCAD.Vector(
                    0, 0, 1) and f.Orientation == 'Forward':
                break

        PathJob.Create('Job', [cut], None)

        profile = PathProfileFaces.Create('Profile Faces')
        profile.Base = (cut, face)
        profile.StepDown = 5
        # set start and final depth in order to eliminate effects of stock (and its default values)
        profile.setExpression('StartDepth', None)
        profile.StartDepth = 10
        profile.setExpression('FinalDepth', None)
        profile.FinalDepth = 0

        profile.processHoles = True
        profile.processPerimeter = True
        doc.recompute()

        dogbone = PathDressupDogbone.Create(profile)
        doc.recompute()

        dog = dogbone.Proxy
        locs = sorted([bone[1] for bone in dog.bones],
                      key=lambda xy: xy[0] * 1000 + xy[1])

        def formatBoneLoc(pt):
            return "(%.2f, %.2f)" % (pt[0], pt[1])

        # Make sure we get 8 bones, 2 in each corner (different heights)
        # with start point changes it passes back over the same spot multiple times, so just make sure they are in the right locations
        # self.assertEqual(len(locs), 8)
        self.assertEqual("(27.50, 27.50)", formatBoneLoc(locs[0]))
        self.assertEqual("(27.50, 27.50)", formatBoneLoc(locs[1]))
        self.assertEqual("(27.50, 72.50)", formatBoneLoc(locs[2]))
        self.assertEqual("(27.50, 72.50)", formatBoneLoc(locs[3]))
        self.assertEqual("(72.50, 27.50)", formatBoneLoc(locs[4]))
        self.assertEqual("(72.50, 27.50)", formatBoneLoc(locs[5]))
        self.assertEqual("(72.50, 72.50)", formatBoneLoc(locs[6]))
        self.assertEqual("(72.50, 72.50)", formatBoneLoc(locs[7]))

        FreeCAD.closeDocument("TestDressupDogbone")
Ejemplo n.º 18
0
def fcvec(x):
    if len(x) == 2:
        return (App.Vector(x[0], x[1], 0))
    else:
        return (App.Vector(x[0], x[1], x[2]))
Ejemplo n.º 19
0
def isDrillable(obj, candidate, tooldiameter=None, includePartials=False):
    """
    Checks candidates to see if they can be drilled.
    Candidates can be either faces - circular or cylindrical or circular edges.
    The tooldiameter can be optionally passed.  if passed, the check will return
    False for any holes smaller than the tooldiameter.
    obj=Shape
    candidate = Face or Edge
    tooldiameter=float
    """
    PathLog.track('obj: {} candidate: {} tooldiameter {}'.format(
        obj, candidate, tooldiameter))
    drillable = False
    try:
        if candidate.ShapeType == 'Face':
            face = candidate
            # eliminate flat faces
            if (round(face.ParameterRange[0], 8) == 0.0) and (round(
                    face.ParameterRange[1], 8) == round(math.pi * 2, 8)):
                for edge in face.Edges:  # Find seam edge and check if aligned to Z axis.
                    if (isinstance(edge.Curve, Part.Line)):
                        PathLog.debug("candidate is a circle")
                        v0 = edge.Vertexes[0].Point
                        v1 = edge.Vertexes[1].Point
                        #check if the cylinder seam is vertically aligned.  Eliminate tilted holes
                        if (numpy.isclose(v1.sub(v0).x, 0, rtol=1e-05, atol=1e-06)) and \
                                (numpy.isclose(v1.sub(v0).y, 0, rtol=1e-05, atol=1e-06)):
                            drillable = True
                            # vector of top center
                            lsp = Vector(face.BoundBox.Center.x,
                                         face.BoundBox.Center.y,
                                         face.BoundBox.ZMax)
                            # vector of bottom center
                            lep = Vector(face.BoundBox.Center.x,
                                         face.BoundBox.Center.y,
                                         face.BoundBox.ZMin)
                            # check if the cylindrical 'lids' are inside the base
                            # object.  This eliminates extruded circles but allows
                            # actual holes.
                            if obj.isInside(lsp, 1e-6, False) or obj.isInside(
                                    lep, 1e-6, False):
                                PathLog.track(
                                    "inside check failed. lsp: {}  lep: {}".
                                    format(lsp, lep))
                                drillable = False
                            # eliminate elliptical holes
                            elif not hasattr(face.Surface, "Radius"):
                                PathLog.debug(
                                    "candidate face has no radius attribute")
                                drillable = False
                            else:
                                if tooldiameter is not None:
                                    drillable = face.Surface.Radius >= tooldiameter / 2
                                else:
                                    drillable = True
            elif type(face.Surface) == Part.Plane and PathGeom.pointsCoincide(
                    face.Surface.Axis, FreeCAD.Vector(0, 0, 1)):
                if len(face.Edges) == 1 and type(
                        face.Edges[0].Curve) == Part.Circle:
                    center = face.Edges[0].Curve.Center
                    if obj.isInside(center, 1e-6, False):
                        if tooldiameter is not None:
                            drillable = face.Edges[
                                0].Curve.Radius >= tooldiameter / 2
                        else:
                            drillable = True
        else:
            for edge in candidate.Edges:
                if isinstance(edge.Curve, Part.Circle) and (includePartials or
                                                            edge.isClosed()):
                    PathLog.debug("candidate is a circle or ellipse")
                    if not hasattr(edge.Curve, "Radius"):
                        PathLog.debug("No radius.  Ellipse.")
                        drillable = False
                    else:
                        PathLog.debug("Has Radius, Circle")
                        if tooldiameter is not None:
                            drillable = edge.Curve.Radius >= tooldiameter / 2
                            if not drillable:
                                FreeCAD.Console.PrintMessage(
                                    "Found a drillable hole with diameter: {}: "
                                    "too small for the current tool with "
                                    "diameter: {}".format(
                                        edge.Curve.Radius * 2, tooldiameter))
                        else:
                            drillable = True
        PathLog.debug("candidate is drillable: {}".format(drillable))
    except Exception as ex:
        PathLog.warning(
            translate("PathUtils",
                      "Issue determine drillability: {}").format(ex))
    return drillable
Ejemplo n.º 20
0
def mirror(objlist, p1, p2):
    """Create a mirror object from the provided list and line.

    It creates a `Part::Mirroring` object from the given `objlist` using
    a plane that is defined by the two given points `p1` and `p2`,
    and either

    - the Draft working plane normal, or
    - the negative normal provided by the camera direction
      if the working plane normal does not exist and the graphical interface
      is available.

    If neither of these two is available, it uses as normal the +Z vector.

    Parameters
    ----------
    objlist: single object or a list of objects
        A single object or a list of objects.

    p1: Base::Vector3
        Point 1 of the mirror plane. It is also used as the `Placement.Base`
        of the resulting object.

    p2: Base::Vector3
        Point 1 of the mirror plane.

    Returns
    -------
    None
        If the operation fails.

    list
        List of `Part::Mirroring` objects, or a single one
        depending on the input `objlist`.

    To Do
    -----
    Implement a mirror tool specific to the workbench that does not
    just use `Part::Mirroring`. It should create a derived object,
    that is, it should work similar to `Draft.offset`.
    """
    utils.print_header('mirror', "Create mirror")

    if not objlist:
        _err(translate("draft", "No object given"))
        return

    if p1 == p2:
        _err(translate("draft", "The two points are coincident"))
        return

    if not isinstance(objlist, list):
        objlist = [objlist]

    if hasattr(App, "DraftWorkingPlane"):
        norm = App.DraftWorkingPlane.getNormal()
    elif App.GuiUp:
        norm = Gui.ActiveDocument.ActiveView.getViewDirection().negative()
    else:
        norm = App.Vector(0, 0, 1)

    pnorm = p2.sub(p1).cross(norm).normalize()

    result = []

    for obj in objlist:
        mir = App.ActiveDocument.addObject("Part::Mirroring", "mirror")
        mir.Label = obj.Label + " (" + translate("draft", "mirrored") + ") "
        mir.Source = obj
        mir.Base = p1
        mir.Normal = pnorm
        gui_utils.format_object(mir, obj)
        result.append(mir)

    if len(result) == 1:
        result = result[0]
        gui_utils.select(result)

    return result
Ejemplo n.º 21
0
    def settarget(self):
        '''set the target depending on the mouse wheel roll and mode key'''
        if self.imode == 3:
            print "SET IMODE 3"
            ef = self.ef

            self.dials.setValue(min(ef.mouseWheel, 99))
            self.setsharp3(min(ef.mouseWheel, 99))
            #return

        if self.imode == 4:
            print "SET IMODE 4"
            self.settarget4()
            return

        dok = self.helperDok()
        pl = len(self.points)
        self.dial.setMaximum(pl - 1)
        pos = self.dial.value()

        if pos == 0: lpos = pl - 1
        else: lpos = pos - 1

        if pos == pl - 1: rpos = 0
        else: rpos = pos + 1
        #		print ('pl,pos,lpos,rpos',pl,pos,lpos,rpos)

        if self.imode <> 3:
            diff = FreeCAD.Vector()
            ef = self.ef
            if ef.key in ['x', 'y', 'z']:
                kx, ky, kz = 0, 0, 0
                if ef.key == 'x':
                    kx = ef.mouseWheel * FreeCAD.ParamGet(
                        'User parameter:Plugins/nurbs').GetFloat(
                            "MoveWheelStep", 1)
                if ef.key == 'y':
                    ky = ef.mouseWheel * FreeCAD.ParamGet(
                        'User parameter:Plugins/nurbs').GetFloat(
                            "MoveWheelStep", 1)
                if ef.key == 'z':
                    kz = ef.mouseWheel * FreeCAD.ParamGet(
                        'User parameter:Plugins/nurbs').GetFloat(
                            "MoveWheelStep", 1)

                #changed point
                diff = FreeCAD.Vector(kx, ky, kz)
                t = self.points[pos] + diff
            elif ef.key == 't':
                a = FreeCAD.Vector(self.points[lpos]) - FreeCAD.Vector(
                    self.points[rpos])
                a.normalize()
                diff = a.multiply(
                    ef.mouseWheel *
                    FreeCAD.ParamGet('User parameter:Plugins/nurbs').GetFloat(
                        "MoveWheelStep", 1))
                t = self.points[pos] + diff
            elif ef.key == 'n' or ef.key == 'b':
                a = FreeCAD.Vector(self.points[lpos]) - FreeCAD.Vector(
                    self.points[rpos])
                b = FreeCAD.Vector(self.points[lpos]) - FreeCAD.Vector(
                    self.points[pos])
                c = a.cross(b)
                if ef.key == 'n': d = c.cross(a)
                else: d = c
                d.normalize()
                diff = d.multiply(
                    ef.mouseWheel *
                    FreeCAD.ParamGet('User parameter:Plugins/nurbs').GetFloat(
                        "MoveWheelStep", 1))
                t = self.points[pos] + diff
            elif ef.key == 'r':
                d = FreeCAD.Vector(self.points[pos][0], self.points[pos][1],
                                   0).normalize()
                diff = d.multiply(
                    ef.mouseWheel *
                    FreeCAD.ParamGet('User parameter:Plugins/nurbs').GetFloat(
                        "MoveWheelStep", 1))
                t = self.points[pos] + diff
            else:
                print("mode not implemented ", ef.key)
                t = self.points[pos]

            #self.target(dok, t)
            print("settarget cc imode", self.imode)
            print("diff", diff)
            if self.imode == 1:
                self.target(dok,
                            coordlist=[
                                self.points[pos - 1] + diff, t,
                                self.points[pos + 1] + diff
                            ])
            else:
                self.target(dok, coordlist=[t])

    #		try: dok.Sphere
    #		except:
    #			s=dok.addObject("Part::Sphere","Sphere")
    #			s.Radius=10000000
    #			s.ViewObject.Selectable=False
    #			s.ViewObject.ShapeColor=(1.,1.,1.)
    #			s.ViewObject.DisplayMode = u"Shaded"
    #			s.ViewObject.DisplayMode = u"Shaded"

    # create or get traget curve

            pp = self.points

            if pos > 0: pp2 = pp[:pos] + [t] + pp[pos + 1:]
            else: pp2 = [t] + pp[pos + 1:]

            # bspline curve
            bs = dok.BSpline.Shape.Edge1.Curve.copy()
            bs.setPole(pos + 1, FreeCAD.Vector(t))
            if self.imode == 1:
                bs.setPole(pos, self.points[pos - 1] + diff)
                bs.setPole(pos + 2, self.points[pos + 1] + diff)
            dok.BSpline.Shape = bs.toShape()
            pol = Part.makePolygon(pp2 + [pp2[0]])

        else:
            pp2 = self.points

            # pole polygon
            pol = Part.makePolygon(pp2 + [pp2[0]])
            #		bb.Shape=pol

            bs = dok.BSpline.Shape.Edge1.Curve.copy()

        try:
            bb = dok.TargetCurve
            bax = dok.TargetExtra

        except:
            bb = dok.addObject('Part::Feature', 'TargetCurve')
            bax = dok.addObject('Part::Feature', 'TargetExtra')

        bax.ViewObject.LineColor = (1.0, 1.0, 0.0)

        pp3 = []
        ppax = []

        if self.source == 'Backbone':
            print "recompute Backbone #########################################"
            xV = FreeCAD.Vector(100, 0, 0)
            yV = FreeCAD.Vector(0, 100, 0)
            zV = FreeCAD.Vector(0, 0, 141)

            source = self.getsource()
            needle = source.InList[0]
            curvea, bba, scaler, twister = needle.Proxy.Model()

            for i, p in enumerate(pp2):
                # print (i,twister[i],scaler[i])
                [xa, ya, za] = twister[i]

                if pos == i:
                    xa += self.rotx
                    ya += self.roty
                    za += self.rotz

                if pos == i:
                    xa = self.rotx
                    ya = self.roty
                    za = self.rotz

                p2 = FreeCAD.Placement()
                p2.Rotation = FreeCAD.Rotation(FreeCAD.Vector(
                    0, 0, 1), za).multiply(
                        FreeCAD.Rotation(FreeCAD.Vector(0, 1, 0), ya).multiply(
                            FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), xa)))

                ph = FreeCAD.Placement()
                ph.Base = xV
                xR = p2.multiply(ph).Base
                ph = FreeCAD.Placement()
                ph.Base = yV
                yR = p2.multiply(ph).Base
                ph = FreeCAD.Placement()
                ph.Base = zV
                zR = p2.multiply(ph).Base

                p = FreeCAD.Vector(p)

                if 1:
                    pp = Part.makePolygon([p, p + xR, p + xR + yR, p])
                    ps = Part.Face(pp)
                    ppax.append(ps)
                    pp = Part.makePolygon([p, p + yR, p + xR + yR, p])
                    ppax.append(Part.Face(pp))
                    pp = Part.makePolygon([p, p + zR, p + xR + yR, p])
                    ppax.append(Part.Face(pp))

        # all together
        bb.Shape = Part.Compound([pol])
        if ppax <> []:
            bax.Shape = Part.Compound(ppax + [bs.toShape()])

        dok.recompute()

        bb.ViewObject.LineColor = (1.0, 0.6, .0)
        bb.ViewObject.LineWidth = 1
        bb.ViewObject.PointColor = (.8, 0.4, .0)
        bb.ViewObject.PointSize = 8
        bax.ViewObject.Selectable = False

        col = []
        for i in range(len(bax.Shape.Faces)):
            tt = i % 3
            if tt == 0: col.append((1., 0., 0.))
            elif tt == 1: col.append((0., 1., 0.))
            else: col.append((0., 0., 1.))
        # bax.ViewObject.DiffuseColor=col
        bax.ViewObject.LineColor = (1.0, 0.0, 0.0)
    FreeCAD.newDocument(DOC_NAME)
    FreeCAD.setActiveDocument(DOC_NAME)
    DOC = FreeCAD.activeDocument()
else:
    clear_doc()

# EPS= tolerance to use to cut the parts
EPS = 0.10
EPS_C = EPS * -0.5

# transformer
transformer = Part.makeBox(65.4, 50.8, 87.4776)

# ferroxcube_1
ferroxcube_1 = Part.makeBox(28, 16, 87.4776)
ferroxcube_1_vector = FreeCAD.Vector(18.7, 17.4, 0)
ferroxcube_1.translate(ferroxcube_1_vector)

# cut transformer with ferroxcube_1
transformer = transformer.cut(ferroxcube_1)

# coil
coil = Part.makeBox(65.4, 50.8, 33.3248)

# ferroxcube_2
ferroxcube_2 = Part.makeBox(32, 20, 33.3248)
ferroxcube_2_vector = FreeCAD.Vector(16.7, 15.4, 0)
ferroxcube_2.translate(ferroxcube_2_vector)

# cut coil with ferroxcube_2
coil = coil.cut(ferroxcube_2)
Ejemplo n.º 23
0
    def getVolume(self, fp, level, return_shape=False):
        """Return the fluid volume inside the tank, provided the filling level.

        Keyword arguments:
        fp -- Part::FeaturePython object affected.
        level -- Percentage of filling level (interval [0, 1]).
        return_shape -- False if the tool should return the fluid volume value,
        True if the tool should return the volume shape.
        """
        if level <= 0.0:
            if return_shape:
                return Part.Vertex()
            return Units.Quantity(0.0, Units.Volume)
        if level >= 1.0:
            if return_shape:
                return fp.Shape.copy()
            return Units.Quantity(fp.Shape.Volume, Units.Volume)

        # Build up the cutting box
        bbox = fp.Shape.BoundBox
        dx = bbox.XMax - bbox.XMin
        dy = bbox.YMax - bbox.YMin
        dz = bbox.ZMax - bbox.ZMin

        box = App.ActiveDocument.addObject("Part::Box", "Box")
        length_format = USys.getLengthFormat()
        box.Placement = Placement(
            Vector(bbox.XMin - dx, bbox.YMin - dy, bbox.ZMin - dz),
            Rotation(App.Vector(0, 0, 1), 0))
        box.Length = length_format.format(3.0 * dx)
        box.Width = length_format.format(3.0 * dy)
        box.Height = length_format.format((1.0 + level) * dz)

        # Create a new object on top of a copy of the tank shape
        Part.show(fp.Shape.copy())
        tank = App.ActiveDocument.Objects[-1]

        # Compute the common boolean operation
        App.ActiveDocument.recompute()
        common = App.activeDocument().addObject("Part::MultiCommon",
                                                "TankVolHelper")
        common.Shapes = [tank, box]
        App.ActiveDocument.recompute()
        if len(common.Shape.Solids) == 0:
            # The common operation is failing, let's try moving a bit the free
            # surface
            msg = QtGui.QApplication.translate(
                "ship_console",
                "Tank volume operation failed. The tool is retrying that"
                " slightly moving the free surface position", None)
            App.Console.PrintWarning(msg + '\n')
            rand_bounds = 0.01 * dz
            i = 0
            while len(common.Shape.Solids
                      ) == 0 and i < COMMON_BOOLEAN_ITERATIONS:
                i += 1
                box.Height = length_format.format(
                    (1.0 + level) * dz +
                    random.uniform(-random_bounds, random_bounds))
                App.ActiveDocument.recompute()

        if return_shape:
            ret_value = common.Shape.copy()
        else:
            ret_value = Units.Quantity(common.Shape.Volume, Units.Volume)

        App.ActiveDocument.removeObject(common.Name)
        App.ActiveDocument.removeObject(tank.Name)
        App.ActiveDocument.removeObject(box.Name)
        App.ActiveDocument.recompute()

        return ret_value
Ejemplo n.º 24
0
 def testWall(self):
     App.Console.PrintLog('Checking Arch Wall...\n')
     l = Draft.makeLine(App.Vector(0, 0, 0), App.Vector(-2, 0, 0))
     w = Arch.makeWall(l)
     self.failUnless(w, "Arch Wall failed")
Ejemplo n.º 25
0
    def execute(self, obj):
        if len(obj.InList) != 1:
            return
        if Draft.getType(obj.InList[0]) != "Structure":
            return
        if not obj.InList[0].Shape:
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.InList[0]
        wire = obj.Base.Shape.Wires[0]
        if hasattr(obj, "Rounding"):
            #print obj.Rounding
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire, radius)
        bpoint, bvec = self.getBaseAndAxis(obj)
        if not bpoint:
            return
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0, 0, -1))
        size = (ArchCommands.projectToVector(father.Shape.copy(), axis)).Length
        if hasattr(obj, "Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)  #.normalize()
                # don't normalize so the vector can also be used to determine the distance
                size = axis.Length
        #print axis
        #print size
        if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size:
            return

        # all tests ok!
        pl = obj.Placement
        import Part
        circle = Part.makeCircle(obj.Diameter.Value / 2, bpoint, bvec)
        circle = Part.Wire(circle)
        try:
            bar = wire.makePipeShell([circle], True, False, 2)
        except:
            print "Arch: error sweeping rebar profile along the base sketch"
            return
        # building final shape
        shapes = []
        if obj.Amount == 1:
            offset = DraftVecUtils.scaleTo(axis, size / 2)
            bar.translate(offset)
            shapes.append(bar)
            if hasattr(obj, "Spacing"):
                obj.Spacing = 0
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis, obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            vinterval = DraftVecUtils.scaleTo(axis, interval)
            for i in range(obj.Amount):
                if i == 0:
                    if baseoffset:
                        bar.translate(baseoffset)
                    shapes.append(bar)
                else:
                    bar = bar.copy()
                    bar.translate(vinterval)
                    shapes.append(bar)
            if hasattr(obj, "Spacing"):
                obj.Spacing = interval
        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl
Ejemplo n.º 26
0
    def testWallMultiMatAlign(self):
        App.Console.PrintLog(
            'Checking Arch Wall with MultiMaterial and 3 alignments...\n')
        matA = Arch.makeMaterial()
        matB = Arch.makeMaterial()
        matMulti = Arch.makeMultiMaterial()
        matMulti.Materials = [matA, matB]
        matMulti.Thicknesses = [100,
                                200]  # total width different from default 200
        pts = [
            App.Vector(0, 0, 0),
            App.Vector(1000, 0, 0),
            App.Vector(1000, 1000, 0),
            App.Vector(2000, 1000, 0)
        ]
        # wall based on wire:
        wire = Draft.makeWire(pts)
        wallWire = Arch.makeWall(wire)
        wallWire.Material = matMulti
        # wall based on sketch:
        sketch = App.activeDocument().addObject('Sketcher::SketchObject',
                                                'Sketch')
        sketch.addGeometry([
            Part.LineSegment(pts[0], pts[1]),
            Part.LineSegment(pts[1], pts[2]),
            Part.LineSegment(pts[2], pts[3])
        ])
        wallSketch = Arch.makeWall(sketch)
        wallSketch.Material = matMulti

        alignLst = ["Left", "Center", "Right"]
        checkLst = [[App.Vector(0, -300, 0),
                     App.Vector(2000, 1000, 0)],
                    [App.Vector(0, -150, 0),
                     App.Vector(2000, 1150, 0)],
                    [App.Vector(0, 0, 0),
                     App.Vector(2000, 1300, 0)]]
        for i in range(3):
            wallWire.Align = alignLst[i]
            wallSketch.Align = alignLst[i]
            App.ActiveDocument.recompute()
            for box in [wallWire.Shape.BoundBox, wallSketch.Shape.BoundBox]:
                ptMin = App.Vector(box.XMin, box.YMin, 0)
                self.failUnless(
                    ptMin.isEqual(checkLst[i][0], 1e-8),
                    "Arch Wall with MultiMaterial and 3 alignments failed")
                ptMax = App.Vector(box.XMax, box.YMax, 0)
                self.failUnless(
                    ptMax.isEqual(checkLst[i][1], 1e-8),
                    "Arch Wall with MultiMaterial and 3 alignments failed")
def getpointsOfUShapeRebar(
    FacePRM: Tuple[Tuple[float, float], Tuple[float, float]],
    r_cover: float,
    l_cover: float,
    b_cover: float,
    t_cover: float,
    orientation: Literal["Bottom", "Top", "Left", "Right"],
    diameter: float,
    face_normal: FreeCAD.Vector,
) -> List[FreeCAD.Vector]:
    """getpointsOfUShapeRebar(FacePRM, RightCover, LeftCover, BottomCover,
    TopCover, Orientation, Diameter, FaceNormal):
    Return points of the UShape rebar in the form of array for sketch.

    It takes four different orientations input i.e. 'Bottom', 'Top', 'Left',
    'Right'.
    """
    center_x = FacePRM[1][0]
    center_y = FacePRM[1][1]
    # When Left/Rear Face of structure is selected
    if round(face_normal[0]) == -1 or round(face_normal[1]) == 1:
        center_x = -center_x
    # When Bottom Face of structure is selected
    elif round(face_normal[2]) == -1:
        center_y = -center_y
    if orientation == "Bottom":
        l_cover += diameter / 2
        r_cover += diameter / 2
        b_cover += diameter / 2
        x1 = center_x - FacePRM[0][0] / 2 + l_cover
        y1 = center_y + FacePRM[0][1] / 2 - t_cover
        x2 = center_x - FacePRM[0][0] / 2 + l_cover
        y2 = center_y - FacePRM[0][1] / 2 + b_cover
        x3 = center_x + FacePRM[0][0] / 2 - r_cover
        y3 = center_y - FacePRM[0][1] / 2 + b_cover
        x4 = center_x + FacePRM[0][0] / 2 - r_cover
        y4 = center_y + FacePRM[0][1] / 2 - t_cover
    elif orientation == "Top":
        l_cover += diameter / 2
        r_cover += diameter / 2
        t_cover += diameter / 2
        x1 = center_x - FacePRM[0][0] / 2 + l_cover
        y1 = center_y - FacePRM[0][1] / 2 + b_cover
        x2 = center_x - FacePRM[0][0] / 2 + l_cover
        y2 = center_y + FacePRM[0][1] / 2 - t_cover
        x3 = center_x + FacePRM[0][0] / 2 - r_cover
        y3 = center_y + FacePRM[0][1] / 2 - t_cover
        x4 = center_x + FacePRM[0][0] / 2 - r_cover
        y4 = center_y - FacePRM[0][1] / 2 + b_cover
    elif orientation == "Left":
        l_cover += diameter / 2
        t_cover += diameter / 2
        b_cover += diameter / 2
        x1 = center_x + FacePRM[0][0] / 2 - r_cover
        y1 = center_y + FacePRM[0][1] / 2 - t_cover
        x2 = center_x - FacePRM[0][0] / 2 + l_cover
        y2 = center_y + FacePRM[0][1] / 2 - t_cover
        x3 = center_x - FacePRM[0][0] / 2 + l_cover
        y3 = center_y - FacePRM[0][1] / 2 + b_cover
        x4 = center_x + FacePRM[0][0] / 2 - r_cover
        y4 = center_y - FacePRM[0][1] / 2 + b_cover
    elif orientation == "Right":
        r_cover += diameter / 2
        t_cover += diameter / 2
        b_cover += diameter / 2
        x1 = center_x - FacePRM[0][0] / 2 + l_cover
        y1 = center_y + FacePRM[0][1] / 2 - t_cover
        x2 = center_x + FacePRM[0][0] / 2 - r_cover
        y2 = center_y + FacePRM[0][1] / 2 - t_cover
        x3 = center_x + FacePRM[0][0] / 2 - r_cover
        y3 = center_y - FacePRM[0][1] / 2 + b_cover
        x4 = center_x - FacePRM[0][0] / 2 + l_cover
        y4 = center_y - FacePRM[0][1] / 2 + b_cover
    else:
        FreeCAD.Console.PrintError(f"Invalid orientation: {orientation}\n")
        return []
    return [
        FreeCAD.Vector(x1, y1, 0),
        FreeCAD.Vector(x2, y2, 0),
        FreeCAD.Vector(x3, y3, 0),
        FreeCAD.Vector(x4, y4, 0),
    ]
Ejemplo n.º 28
0
 def testFrame(self):
     App.Console.PrintLog('Checking Arch Frame...\n')
     l = Draft.makeLine(App.Vector(0, 0, 0), App.Vector(-2, 0, 0))
     p = Draft.makeRectangle(length=.5, height=.5)
     f = Arch.makeFrame(l, p)
     self.failUnless(f, "Arch Frame failed")
Ejemplo n.º 29
0
class Camera:
    """A camera for rendering.

    This object allows to record camera settings from the Coin camera, and to
    reuse them for rendering.

    Camera Orientation is defined by a Rotation Axis and a Rotation Angle,
    applied to 'default camera'.
    Default camera looks from (0,0,1) towards the origin (target is (0,0,-1),
    and the up direction is (0,1,0).

    For more information, see Coin documentation, Camera section.
    <https://developer.openinventor.com/UserGuides/Oiv9/Inventor_Mentor/Cameras_and_Lights/Cameras.html>
    """

    # Enumeration of allowed values for ViewportMapping parameter (see Coin
    # documentation)
    # Nota: Keep following tuple in original order, as relationship between
    # values and indexes matters and is used for reverse transcoding
    VIEWPORTMAPPINGENUM = ("CROP_VIEWPORT_FILL_FRAME",
                           "CROP_VIEWPORT_LINE_FRAME",
                           "CROP_VIEWPORT_NO_FRAME", "ADJUST_CAMERA",
                           "LEAVE_ALONE")

    Prop = namedtuple('Prop', ['Type', 'Group', 'Doc', 'Default'])

    # FeaturePython object properties
    PROPERTIES = {
        "Projection":
        Prop(
            "App::PropertyEnumeration", "Camera",
            QT_TRANSLATE_NOOP("Render",
                              "Type of projection: Perspective/Orthographic"),
            ("Perspective", "Orthographic")),
        "Placement":
        Prop("App::PropertyPlacement", "",
             QT_TRANSLATE_NOOP("Render", "Placement of camera"),
             App.Placement(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 0)),
        "ViewportMapping":
        Prop("App::PropertyEnumeration", "Camera",
             QT_TRANSLATE_NOOP("Render", "(See Coin documentation)"),
             VIEWPORTMAPPINGENUM),
        "AspectRatio":
        Prop("App::PropertyFloat", "Camera",
             QT_TRANSLATE_NOOP("Render", "Ratio width/height of the camera."),
             1.0),
        "NearDistance":
        Prop("App::PropertyDistance", "Camera",
             QT_TRANSLATE_NOOP("Render", "Near distance, for clipping"), 0.0),
        "FarDistance":
        Prop("App::PropertyDistance", "Camera",
             QT_TRANSLATE_NOOP("Render", "Far distance, for clipping"), 200.0),
        "FocalDistance":
        Prop("App::PropertyDistance", "Camera",
             QT_TRANSLATE_NOOP("Render", "Focal distance"), 100.0),
        "Height":
        Prop("App::PropertyLength", "Camera",
             QT_TRANSLATE_NOOP("Render", "Height, for orthographic camera"),
             5.0),
        "HeightAngle":
        Prop(
            "App::PropertyAngle", "Camera",
            QT_TRANSLATE_NOOP("Render",
                              "Height angle, for perspective camera"), 60),
    }
    # ~FeaturePython object properties

    _fpos = dict()  # FeaturePython objects

    @classmethod
    def set_properties(cls, fpo):
        """Set underlying FeaturePython object's properties"""
        for name in cls.PROPERTIES.keys() - set(fpo.PropertiesList):
            spec = cls.PROPERTIES[name]
            prop = fpo.addProperty(spec.Type, name, spec.Group, spec.Doc, 0)
            setattr(prop, name, spec.Default)

    def __init__(self, fpo):
        """Camera Initializer

        Arguments
        ---------
        fpo: a FeaturePython object created with FreeCAD.addObject
        """
        self.type = "Camera"
        fpo.Proxy = self
        self.fpo = fpo
        self.set_properties(fpo)

    @property
    def fpo(self):
        """Underlying FeaturePython object getter"""
        return self._fpos[id(self)]

    @fpo.setter
    def fpo(self, new_fpo):
        """Underlying FeaturePython object setter"""
        self._fpos[id(self)] = new_fpo

    @staticmethod
    def create(document=None):
        """Create a Camera object in a document

        Factory method to create a new camera object.
        The camera is created into the active document (default).
        Optionally, it is possible to specify a target document, in that case
        the camera is created in the given document.

        If Gui is up, the camera is initialized to current active camera;
        otherwise it is set to DEFAULT_CAMERA_STRING.
        This method also create the FeaturePython and the ViewProviderCamera
        related objects.

        Params:
        document: the document where to create camera (optional)

        Returns:
        The newly created Camera object, the FeaturePython object and the
        ViewProviderCamera object"""

        doc = document if document else App.ActiveDocument
        fpo = doc.addObject("App::FeaturePython", "Camera")
        cam = Camera(fpo)
        viewp = ViewProviderCamera(fpo.ViewObject)
        if App.GuiUp:
            viewp.set_camera_from_gui()
        else:
            set_cam_from_coin_string(fpo, DEFAULT_CAMERA_STRING)
        App.ActiveDocument.recompute()
        return cam, fpo, viewp

    def onDocumentRestored(self, fpo):
        """Callback triggered when document is restored"""
        self.type = "Camera"
        fpo.Proxy = self
        self.fpo = fpo
        self.set_properties(fpo)

    def execute(self, fpo):
        # pylint: disable=no-self-use
        """Callback triggered on document recomputation (mandatory).
        It mainly draws the camera graphical representation"""

    def point_at(self, point):
        """Make camera point at a given target point

        Parameters:
        -----------
        point -- point to point at (must have x, y, z properties)
        """
        fpo = self.fpo
        current_target = fpo.Placement.Rotation.multVec(App.Vector(0, 0, -1))
        base = fpo.Placement.Base
        new_target = App.Vector(point.x - base.x, point.y - base.y,
                                point.z - base.z)
        axis = current_target.cross(new_target)
        if not axis.Length:
            # Don't try to rotate if axis is a null vector...
            return
        angle = degrees(new_target.getAngle(current_target))
        rotation = App.Rotation(axis, angle)

        fpo.Placement.Rotation = rotation.multiply(fpo.Placement.Rotation)
Ejemplo n.º 30
0
    def areaOpShapes(self, obj):
        '''areaOpShapes(obj) ... return top face'''
        # Facing is done either against base objects
        holeShape = None

        PathLog.debug('depthparams: {}'.format([i for i in self.depthparams]))

        if obj.Base:
            PathLog.debug("obj.Base: {}".format(obj.Base))
            faces = []
            holes = []
            holeEnvs = []
            oneBase = [obj.Base[0][0], True]
            sub0 = getattr(obj.Base[0][0].Shape, obj.Base[0][1][0])
            minHeight = sub0.BoundBox.ZMax

            for b in obj.Base:
                for sub in b[1]:
                    shape = getattr(b[0].Shape, sub)
                    if isinstance(shape, Part.Face):
                        faces.append(shape)
                        if shape.BoundBox.ZMin < minHeight:
                            minHeight = shape.BoundBox.ZMin
                        # Limit to one model base per operation
                        if oneBase[0] is not b[0]:
                            oneBase[1] = False
                        if numpy.isclose(abs(shape.normalAt(0, 0).z), 1):  # horizontal face
                            # Analyze internal closed wires to determine if raised or a recess
                            for wire in shape.Wires[1:]:
                                if obj.ExcludeRaisedAreas:
                                    ip = self.isPocket(b[0], shape, wire)
                                    if ip is False:
                                        holes.append((b[0].Shape, wire))
                                else:
                                    holes.append((b[0].Shape, wire))
                    else:
                        PathLog.warning('The base subobject, "{0}," is not a face. Ignoring "{0}."'.format(sub))

            if obj.ExcludeRaisedAreas and len(holes) > 0:
                for shape, wire in holes:
                    f = Part.makeFace(wire, 'Part::FaceMakerSimple')
                    env = PathUtils.getEnvelope(shape, subshape=f, depthparams=self.depthparams)
                    holeEnvs.append(env)
                    holeShape = Part.makeCompound(holeEnvs)

            PathLog.debug("Working on a collection of faces {}".format(faces))
            planeshape = Part.makeCompound(faces)

        # If no base object, do planing of top surface of entire model
        else:
            planeshape = Part.makeCompound([base.Shape for base in self.model])
            PathLog.debug("Working on a shape {}".format(obj.Label))

        # Find the correct shape depending on Boundary shape.
        PathLog.debug("Boundary Shape: {}".format(obj.BoundaryShape))
        bb = planeshape.BoundBox

        # Apply offset for clearing edges
        offset = 0
        if obj.ClearEdges:
            offset = self.radius + 0.1

        bb.XMin = bb.XMin - offset
        bb.YMin = bb.YMin - offset
        bb.XMax = bb.XMax + offset
        bb.YMax = bb.YMax + offset

        if obj.BoundaryShape == 'Boundbox':
            bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin), FreeCAD.Vector(0, 0, 1))
            env = PathUtils.getEnvelope(partshape=bbperim, depthparams=self.depthparams)
            if obj.ExcludeRaisedAreas and oneBase[1]:
                includedFaces = self.getAllIncludedFaces(oneBase[0], env, faceZ=minHeight)
                if len(includedFaces) > 0:
                    includedShape = Part.makeCompound(includedFaces)
                    includedEnv = PathUtils.getEnvelope(oneBase[0].Shape, subshape=includedShape, depthparams=self.depthparams)
                    env = env.cut(includedEnv)
        elif obj.BoundaryShape == 'Stock':
            stock = PathUtils.findParentJob(obj).Stock.Shape
            env = stock

            if obj.ExcludeRaisedAreas and oneBase[1]:
                includedFaces = self.getAllIncludedFaces(oneBase[0], stock, faceZ=minHeight)
                if len(includedFaces) > 0:
                    stockEnv = PathUtils.getEnvelope(partshape=stock, depthparams=self.depthparams)
                    includedShape = Part.makeCompound(includedFaces)
                    includedEnv = PathUtils.getEnvelope(oneBase[0].Shape, subshape=includedShape, depthparams=self.depthparams)
                    env = stockEnv.cut(includedEnv)
        elif obj.BoundaryShape == 'Perimeter':
            if obj.ClearEdges:
                psZMin = planeshape.BoundBox.ZMin
                ofstShape = PathUtils.getOffsetArea(planeshape,
                                                    self.radius * 1.25,
                                                    plane=planeshape)
                ofstShape.translate(FreeCAD.Vector(0.0, 0.0, psZMin - ofstShape.BoundBox.ZMin))
                env = PathUtils.getEnvelope(partshape=ofstShape, depthparams=self.depthparams)
            else:
                env = PathUtils.getEnvelope(partshape=planeshape, depthparams=self.depthparams)
        elif obj.BoundaryShape == 'Face Region':
            import PathScripts.PathSurfaceSupport as PathSurfaceSupport
            baseShape = oneBase[0].Shape
            psZMin = planeshape.BoundBox.ZMin
            ofstShape = PathUtils.getOffsetArea(planeshape,
                                                self.tool.Diameter * 1.1,
                                                plane=planeshape)
            ofstShape.translate(FreeCAD.Vector(0.0, 0.0, psZMin - ofstShape.BoundBox.ZMin))

            custDepthparams = self._customDepthParams(obj, obj.StartDepth.Value + 0.1, obj.FinalDepth.Value - 0.1)  # only an envelope
            ofstShapeEnv = PathUtils.getEnvelope(partshape=ofstShape, depthparams=custDepthparams)
            env = ofstShapeEnv.cut(baseShape)

        if holeShape:
            PathLog.debug("Processing holes and face ...")
            holeEnv = PathUtils.getEnvelope(partshape=holeShape, depthparams=self.depthparams)
            newEnv = env.cut(holeEnv)
            tup = newEnv, False, 'pathMillFace', 0.0, 'X', obj.StartDepth.Value, obj.FinalDepth.Value
        else:
            PathLog.debug("Processing solid face ...")
            tup = env, False, 'pathMillFace', 0.0, 'X', obj.StartDepth.Value, obj.FinalDepth.Value
        return [tup]