Example #1
0
def angle(f0, f1, v0, e0):
    """f0 - передня поверхня, f1 - задня поверхня, v0 - вершина на різальній кромці, e0 - гвинтова кромка"""
    plane0 = f0.Surface
    curve0 = e0.Curve
    res = plane0.intersect(curve0)  # або common, distToShape
    print "к-ть точок перетину: ", len(res[0])
    #p1=res[0][0] # точка Part.Point перетину
    # але може бути кілька точок перетину, тому використовуйте: elt.Placement.Base isEqual distanceToPoint
    for resi in res[0]:
        if v0.Point.isEqual(resi.toShape().Point, d.P):  # близька до v0
            p1 = resi
    Part.show(p1.toShape())
    vec1 = App.Vector(p1.X, p1.Y, p1.Z)
    vec = curve0.tangent(curve0.parameter(vec1))[0]  # дотична в точці
    vec = vec + vec1  # перемістити в положення
    plane = Part.Plane(vec1, v0.Point, vec)  # площина різання
    Part.show(Part.makeLine(vec1, vec))
    Part.show(Part.makeLine(vec1, (vec - vec1).negative() + vec1))
    uv = plane.parameter(vec1)
    vec2 = plane.normal(uv[0], uv[1])  # нормаль до площини різання
    uv = f1.Surface.parameter(vec1)
    vec3 = f1.Surface.normal(uv[0], uv[1])  # нормаль до задньої поверхні
    a = vec2.getAngle(vec3)  # кінематичний задній кут

    vec2 = vec2 + vec1  # перемістити в положення
    plane = Part.Plane(vec1, v0.Point, vec2)  # основна площина
    Part.show(Part.makeLine(vec1, vec2))
    Part.show(Part.makeLine(vec1, (vec2 - vec1).negative() + vec1))
    uv = plane.parameter(vec1)
    vec4 = plane.normal(uv[0], uv[1])  # нормаль до основної площини
    uv = f0.Surface.parameter(vec1)
    vec5 = f0.Surface.normal(uv[0], uv[1])  # нормаль до передньої поверхні
    g = vec4.getAngle(vec5)  # кінематичний передній кут
    return np.degrees(a), np.degrees(g)
	def StarDiag4_3Sub(self, fp, Sub_prev_i, Sub_i, Sub_next_i):
		# apply index and get Poles list from instance.
		Sub_prev = getattr(fp, 'Poles_%d' % Sub_prev_i)
		Sub = getattr(fp, 'Poles_%d' % Sub_i)
		Sub_next = getattr(fp, 'Poles_%d' % Sub_next_i)

		# do the thing
		# parallelogram diagonal 
		Sub_28_raw = Sub[27] + (Sub[22]-Sub[21])
		# scaled down 75% to spread out center
		Sub_28_scaled = Sub[21] + 0.75 * (Sub_28_raw - Sub[21])

		Plane_prev = Part.Plane(Sub[33],Sub[23],Sub_prev[33])
		Plane_next = Part.Plane(Sub[33],Sub[23],Sub_next[23])

		Sub_28_prev_param = Plane_prev.parameter(Sub_28_scaled)
		Sub_28_prev_proj = Plane_prev.value(Sub_28_prev_param[0],Sub_28_prev_param[1])

		Sub_28_next_param = Plane_next.parameter(Sub_28_scaled)
		Sub_28_next_proj = Plane_next.value(Sub_28_next_param[0],Sub_28_next_param[1])

		Sub[28] = 0.5 * Sub_28_scaled + 0.25 * (Sub_28_prev_proj + Sub_28_next_proj)

		# update instance properties using setattr() and string manipulation to set index
		setattr(fp, 'Poles_%d' % Sub_i, Sub)

		# control leg visualization
		Legs_Diag4 = [0,0]
		Legs_Diag4[0] = Part.LineSegment(Sub[22],Sub[28])
		Legs_Diag4[1] = Part.LineSegment(Sub[27],Sub[28])

		# update instance property. direct assignment
		Legs = fp.Legs
		fp.Legs = Legs + Legs_Diag4
		return 0
Example #3
0
def get_relative_placement(shape1, shape2):
    """returns the placement that must be
    applied to shape1 to move it to shape_2"""
    # https://forum.freecadweb.org/viewtopic.php?f=22&t=44880
    # Assuming that the first 3 vertices of the shape
    # correctly define a plane (not coincident, nor colinear)
    plane1 = Part.Plane(*[v.Point for v in shape1.Vertexes[0:3]])
    plane2 = Part.Plane(*[v.Point for v in shape2.Vertexes[0:3]])
    pl1 = FreeCAD.Placement(plane1.Position, plane1.Rotation)
    pl2 = FreeCAD.Placement(plane2.Position, plane2.Rotation)
    return pl2.multiply(pl1.inverse())
Example #4
0
 def Activated(self):
     sel = FreeCADGui.Selection.getSelection()
     if not len(sel) == 2:
         FreeCAD.Console.PrintError("Select 2 objects !\n")
     for selobj in sel:
         selobj.ViewObject.Visibility = False
     pl = Part.Plane()
     pl.transform(sel[0].Placement.toMatrix())
     d1 = pl.Axis
     pl = Part.Plane()
     pl.transform(sel[1].Placement.toMatrix())
     d2 = pl.Axis
     self.makeCPCFeature(sel[0], sel[1], d1, d2)
Example #5
0
    def test_issue_4456(self):
        """
        0004456: Regression : Part.Plane.Intersect do not accept plane as argument
        """
        p1 = Part.Plane()
        p2 = Part.Plane(Vector(0, 0, 0), Vector(1, 0, 0))

        result = p1.intersect(p2)
        line = result.pop()
        self.assertEqual(line.Location, Vector(0, 0, 0))
        self.assertEqual(line.Direction, Vector(0, 1, 0))
        # We should now have empty list...
        with self.assertRaises(IndexError):
            result.pop()
Example #6
0
    def testChFi2d_AnaFilletAlgo(self):
        v = FreeCAD.Vector
        edge1 = Part.makeLine(v(0,0,0), v(0,10,0))
        edge2 = Part.makeLine(v(0,10,0), v(10,10,0))
        wire = Part.Wire([edge1, edge2])
        pln = Part.Plane()

        with self.assertRaises(TypeError):
            alg = Part.ChFi2d.AnaFilletAlgo(pln)

        alg = Part.ChFi2d.AnaFilletAlgo()
        with self.assertRaises(TypeError):
            alg.init()

        print (alg)
        # Test without shape
        self.assertFalse(alg.perform(1))

        with self.assertRaises(TypeError):
            alg.perform()

        alg = Part.ChFi2d.AnaFilletAlgo(wire, pln)
        alg.init(edge1, edge2, pln)
        alg.init(wire, pln)

        alg = Part.ChFi2d.AnaFilletAlgo(edge1, edge2, pln)
        alg.perform(1.0)

        with self.assertRaises(TypeError):
            alg.result(1)

        result = alg.result()
        curve = result[0].Curve
        self.assertEqual(type(curve), Part.Circle)
        self.assertEqual(curve.Radius, 1.0)
Example #7
0
def ensure_external_earth_is_set(space: "SpaceFeature",
                                 doc=FreeCAD.ActiveDocument):
    sites: List["ContainerFeature"] = list(
        utils.get_elements_by_ifctype("IfcSite", doc))
    ground_bound_box = get_ground_bound_box(sites)
    if space.Shape.BoundBox.ZMin - ground_bound_box.ZMax > 1000:
        return
    ground_shape = Part.Compound([])
    for site in sites:
        ground_shape.add(site.Shape)
    if not ground_shape.BoundBox.isValid():
        ground_shape = Part.Plane().toShape()
    for boundary in space.SecondLevel.Group:
        if boundary.InternalOrExternalBoundary in (
                "INTERNAL",
                "EXTERNAL_EARTH",
                "EXTERNAL_WATER",
                "EXTERNAL_FIRE",
        ):
            continue
        if boundary.InnerBoundaries:
            continue
        if not is_underground(boundary, ground_shape):
            continue
        boundary.InternalOrExternalBoundary = "EXTERNAL_EARTH"
Example #8
0
 def compute_tangents(self):
     tans = list()
     flags = list()
     for i in range(len(self.points)):
         if isinstance(self.points[i].shape,Part.Face):
             for vec in self.points[i].points:
                 u,v = self.points[i].shape.Surface.parameter(FreeCAD.Vector(vec))
                 norm = self.points[i].shape.normalAt(u,v)
                 cp = self.curve.parameter(FreeCAD.Vector(vec))
                 t = self.curve.tangent(cp)[0]
                 pl = Part.Plane(FreeCAD.Vector(),norm)
                 ci = Part.Geom2d.Circle2d()
                 ci.Radius = t.Length * 2
                 w = Part.Wire([ci.toShape(pl)])
                 f = Part.Face(w)
                 #proj = f.project([Part.Vertex(t)])
                 proj = Part.Vertex(t).distToShape(f)[1][0][1]
                 #pt = proj.Vertexes[0].Point
                 #FreeCAD.Console.PrintMessage("Projection %s -> %s\n"%(t,proj))
                 if proj.Length > 1e-7:
                     tans.append(proj)
                     flags.append(True)
                 else:
                     tans.append(FreeCAD.Vector(1,0,0))
                     flags.append(False)
         else:
             for vec in self.points[i].points:
                 tans.append(FreeCAD.Vector(1,0,0))
                 flags.append(False)
     return(tans,flags)
Example #9
0
 def build_param_ortho(self, num=20):
     #surf = ruled_surface(self.rail1.edge, self.rail2.edge).Surface
     mid = self.surf.vIso(0.5)
     #c0 = surf.vIso(0.0)
     #c1 = surf.vIso(1.0)
     #v0 = c0.toShape()
     #v1 = c1.toShape()
     self.inter = interp()
     self.inter.add(0, (self.rail1.edge.Curve.FirstParameter,
                        self.rail2.edge.Curve.FirstParameter))
     pl = Part.Plane()
     for i in range(1, num):
         v = float(i) / (num)
         pt = mid.value(v)
         tan = mid.tangent(v)[0]
         pl.Position = pt
         pl.Axis = tan
         pts0 = self.rail1.edge.Curve.intersectCS(pl)[0]
         pts1 = self.rail2.edge.Curve.intersectCS(pl)[0]
         pt0 = closest_point(pts0, pt)
         pt1 = closest_point(pts1, pt)
         if isinstance(pt0, FreeCAD.Vector) and isinstance(
                 pt1, FreeCAD.Vector):
             p1 = nurbs_tools.nearest_parameter(self.rail1.edge.Curve, pt0)
             p2 = nurbs_tools.nearest_parameter(self.rail2.edge.Curve, pt1)
             self.inter.add(
                 v, (p1, p2)
             )  # (self.rail1.edge.Curve.parameter(pt0), self.rail2.edge.Curve.parameter(pt1)))
         else:
             FreeCAD.Console.PrintError(
                 "Failed to compute points at %f.\n" % v)
     self.inter.add(1, (self.rail1.edge.Curve.LastParameter,
                        self.rail2.edge.Curve.LastParameter))
    def CreateSpiral(self, fp, a):
        m = fp.Profile.Shape.BoundBox.Center  # Center of the profile
        myNumRot = fp.Rotations
        myRadius = m.distanceToLine(fp.Center, fp.Center + fp.Axis)
        myGrowth = Growth
        myPitch = 1.0
        myHeight = myNumRot * myPitch
        myAngle = atan(myGrowth / myPitch)

        assert myGrowth > 0, u"Growth too small"
        assert myNumRot > 0, u"Number of rotations too small"

        aPnt = VEC(0.0, 0.0, 0.0)
        aDir = VEC(2.0 * pi, myPitch, 0.0)
        surf = Part.Cone(aPnt, DIR_Z, 1.0, 0.0)

        line = Part.LineSegment(aPnt, aDir)
        beg = line.value(0)
        end = line.value(aDir.Length * myNumRot)

        # calculate end point for conical helix
        v = myHeight / cos(myAngle)
        u = myNumRot * 2.0 * pi
        segm = Part.LineSegment(beg, VEC(u, v, 0))

        edgeOnSurf = surf.project(segm)
        wire = edgeOnSurf.toShape()

        aPlane = Part.Plane(aPnt, DIR_Z)
        range = (myNumRot + 1) * myGrowth + 1 + myRadius
        aPlane.toShape().project(wire)
        return spiral
Example #11
0
def getMidPlane(fp, fraction):
    midvec = CurvedShapes.vectorMiddle(fp.Shape1.Shape.BoundBox.Center,
                                       fp.Shape2.Shape.BoundBox.Center,
                                       fraction)
    midnorm = CurvedShapes.vectorMiddle(fp.NormalShape1, fp.NormalShape2,
                                        fraction)
    return Part.Plane(midvec, midnorm)
    def StarDiag4_squish(self, fp, N):
        # we are going to average all poles [28] around the loop to define the squish center

        # sum all poles [28]
        Poles_28_total = Base.Vector(0, 0, 0)
        for i in range(N):
            Poles_28_total = Poles_28_total + fp.StarGrid[i][28][0]

        SquishCenter = (1.0 / N) * Poles_28_total

        # do cross products in pairs around the loops to get a list of normal direction approximations
        cross_total = Base.Vector(0, 0, 0)
        for i in range(N - 1):
            cross_total = cross_total + (
                fp.StarGrid[i][28][0] -
                SquishCenter).cross(fp.StarGrid[i + 1][28][0] - SquishCenter)
        # close sequence by looping back
        cross_total = cross_total + (
            fp.StarGrid[N - 1][28][0] -
            SquishCenter).cross(fp.StarGrid[0][28][0] - SquishCenter)

        # define squish plane from squish center and squish normal
        Squish_Plane = Part.Plane(SquishCenter, cross_total)

        # project all diag4 points to this plane.
        projections = [0] * N
        for i in range(N):
            param = Squish_Plane.parameter(fp.StarGrid[i][28][0])
            fp.StarGrid[i][28][0] = Squish_Plane.value(param[0], param[1])
Example #13
0
    def testShapeFix_Shell(self):
        surface = Part.Plane()
        face = surface.toShape(-1, 1, -1, 1)
        shell = Part.Shell([face])

        Part.ShapeFix.Shell()
        with self.assertRaises(TypeError):
            Part.ShapeFix.Face([])

        fix = Part.ShapeFix.Shell(shell)
        fix.init(shell)
        print (fix)
        fix.perform()
        fix.shell()
        fix.shape()
        fix.fixFaceTool()

        fix.setNonManifoldFlag(True)
        fix.fixFaceOrientation(shell)

        self.assertEqual(len(fix.errorFaces().Faces), 0)

        self.assertEqual(fix.numberOfShells(), 1)

        fix.FixFaceMode = True
        self.assertEqual(fix.FixFaceMode, True)

        fix.FixOrientationMode = True
        self.assertEqual(fix.FixOrientationMode, True)
    def StarDiag4_3Sub(self, fp, Sub_prev_i, Sub_i, Sub_next_i):
        # parallelogram diagonal
        Sub_28_raw = fp.StarGrid[Sub_i][27][0] + (fp.StarGrid[Sub_i][22][0] -
                                                  fp.StarGrid[Sub_i][21][0])
        # scaling factor. based on N?
        # no. need to fix this. the scaling factor needs to achieve alignment between neighboring subgrids if they align,
        # and a smooth rotation if they do not align.
        # something...something...angle in the normal or maybe tangent plane. something...(1-cos()) factor.
        if fp.N == 3:
            scale = 0.75  # scaled down 75% to spread out center this works quite well for triangles actually
        if fp.N == 5:
            scale = 1.25  # this is a mess. a single factor doesn't do it. oh well, moving on.

        Sub_28_scaled = fp.StarGrid[Sub_i][21][0] + scale * (
            Sub_28_raw - fp.StarGrid[Sub_i][21][0])

        Plane_prev = Part.Plane(fp.StarGrid[Sub_i][33][0],
                                fp.StarGrid[Sub_i][23][0],
                                fp.StarGrid[Sub_prev_i][33][0])
        Plane_next = Part.Plane(fp.StarGrid[Sub_i][33][0],
                                fp.StarGrid[Sub_i][23][0],
                                fp.StarGrid[Sub_next_i][23][0])

        Sub_28_prev_param = Plane_prev.parameter(Sub_28_scaled)
        Sub_28_prev_proj = Plane_prev.value(Sub_28_prev_param[0],
                                            Sub_28_prev_param[1])

        Sub_28_next_param = Plane_next.parameter(Sub_28_scaled)
        Sub_28_next_proj = Plane_next.value(Sub_28_next_param[0],
                                            Sub_28_next_param[1])

        fp.StarGrid[Sub_i][28][0] = 0.5 * Sub_28_scaled + 0.25 * (
            Sub_28_prev_proj + Sub_28_next_proj)

        # control leg visualization
        Legs_Diag4 = [0, 0]
        Legs_Diag4[0] = Part.LineSegment(fp.StarGrid[Sub_i][22][0],
                                         fp.StarGrid[Sub_i][28][0])
        Legs_Diag4[1] = Part.LineSegment(fp.StarGrid[Sub_i][27][0],
                                         fp.StarGrid[Sub_i][28][0])

        # update instance property. direct assignment
        Legs = fp.Legs
        fp.Legs = Legs + Legs_Diag4
        return 0
Example #15
0
def compute_space_area(space: Part.Feature):
    """Compute both gross and net area"""
    z_min = space.Shape.BoundBox.ZMin
    z_sre = z_min + 1000  # 1 m above ground. See SIA 380:2015 &3.2.3 p.26-27
    sre_plane = Part.Plane(FreeCAD.Vector(0, 0, z_sre),
                           FreeCAD.Vector(0, 0, 1))
    space.Area = space.Shape.common(sre_plane.toShape()).Area
    # TODO: Not valid yet as it return net area. Find a way to get gross space volume
    space.AreaAE = space.Area
def boundbox_from_intersect(curves, pos, normal, doScaleXYZ):
    if len(curves) == 0:
        return None

    plane = Part.Plane(pos, normal)
    xmin = float("inf")
    xmax = float("-inf")
    ymin = float("inf")
    ymax = float("-inf")
    zmin = float("inf")
    zmax = float("-inf")
    found = False
    for n in range(0, len(curves)):
        curve = curves[n]
        ipoints = []
        for edge in curve.Shape.Edges:
            i = plane.intersect(edge.Curve)
            if i:
                for p in i[0]:
                    vert = Part.Vertex(p)
                    if vert.distToShape(edge)[0] < epsilon:
                        ipoints.append(p)
                        found = True

        if found == False:
            return None

        use_x = True
        use_y = True
        use_z = True
        if len(ipoints) > 1:
            use_x = doScaleXYZ[n][0]
            use_y = doScaleXYZ[n][1]
            use_z = doScaleXYZ[n][2]

        for p in ipoints:
            if use_x and p.X > xmax: xmax = p.X
            if use_x and p.X < xmin: xmin = p.X
            if use_y and p.Y > ymax: ymax = p.Y
            if use_y and p.Y < ymin: ymin = p.Y
            if use_z and p.Z > zmax: zmax = p.Z
            if use_z and p.Z < zmin: zmin = p.Z

    if xmin == float("inf") or xmax == float("-inf"):
        xmin = 0
        xmax = 0
    if ymin == float("inf") or ymax == float("-inf"):
        ymin = 0
        ymax = 0
    if zmin == float("inf") or zmax == float("-inf"):
        zmin = 0
        zmax = 0

    return FreeCAD.BoundBox(xmin, ymin, zmin, xmax, ymax, zmax)
Example #17
0
 def __init__(self):
     self._plane = Part.Plane()
     self.nb_of_turns = 2.5
     self.lead = 10.0
     self.cylinder = Part.Cylinder()
     self.cylinder.transform(
         FreeCAD.Placement(FreeCAD.Vector(), FreeCAD.Vector(1, 0, 0),
                           -90).toMatrix())
     self.rational_approx = True
     self.check_splines = False
     self.max_radius = 0
     self._placement = FreeCAD.Placement()
Example #18
0
def vectorMiddlePlaneNormal1(vec1, vec2, normalShape1, normalShape2):
    rota90 = FreeCAD.Rotation(normalShape1.cross(normalShape2), 90)
    normal90 = rota90.multVec(normalShape1)
    plane1 = Part.Plane(vec1, normal90)
    line2 = Part.makeLine(vec2, vec2 + normalShape2)

    p1 = vec1
    isec = plane1.intersect(line2.Curve)
    if isec and len(isec[0]) == 1:
        p1 = CurvedShapes.PointVec(isec[0][0])

    return p1
Example #19
0
 def build_faces(self, surf=None):
     faces = []
     surf = surf or Part.Plane()
     #bs = BoundarySorter(wl)
     for wirelist in self.sort():
         #print(wirelist)
         f = Part.Face(surf, wirelist[0])
         f.validate()
         if len(wirelist) > 1:
             f.cutHoles(wirelist[1:])
             f.validate()
         faces.append(f)
     return faces
Example #20
0
 def tangentTo(self, t, pt):
     v = self.valueAt(t)
     n = self.normalAt(t)
     tanPlane = Part.Plane(v, n)
     line = Part.Line(pt, pt.add(n))
     ptOnPlane = tanPlane.intersect(line)
     res = []
     if isinstance(ptOnPlane, tuple):
         for el in ptOnPlane:
             if isinstance(el, (tuple, list)):
                 for e in el:
                     if isinstance(e, Part.Point):
                         res.append(FreeCAD.Vector(e.X, e.Y, e.Z).sub(v))
     return (res)
Example #21
0
def addFaceWireToSketch(fa, w, sk):
    curves = list()
    const = list()
    pl = Part.Plane()
    for idx in range(len(w.Edges)):
        e, fp, lp = fa.curveOnSurface(w.Edges[idx])
        e3d = e.toShape(pl)
        tc = e3d.Curve.trim(fp, lp)
        curves.append(tc)
    o = int(sk.GeometryCount)
    sk.addGeometry(curves, False)
    for idx in range(len(curves)):
        const.append(Sketcher.Constraint('Block', o + idx))
    sk.addConstraint(const)
Example #22
0
def main():
    obj1 = FreeCAD.ActiveDocument.getObject('CV_BAMB_ELEC_SING_Face25')
    f1 = obj1.Shape.Face1
    surf = f1.Surface
    mid = surf.vIso(0.5)
    c0 = surf.vIso(0.0)
    c1 = surf.vIso(1.0)
    v0 = c0.toShape()
    v1 = c1.toShape()
    num = 200
    inter = interp()
    inter.add(0, (c0.FirstParameter, c1.FirstParameter))
    pl = Part.Plane()
    for i in range(1, num):
        v = float(i) / num
        pt = mid.value(v)
        tan = mid.tangent(v)[0]
        pl.Position = pt
        pl.Axis = tan
        pts0 = c0.intersectCS(pl)[0]
        pts1 = c1.intersectCS(pl)[0]
        pt0 = closest_point(pts0, pt)
        pt1 = closest_point(pts1, pt)
        print(pt0, pt1)
        inter.add(v, (c0.parameter(pt0), c1.parameter(pt1)))
    inter.add(1, (c0.LastParameter, c1.LastParameter))
    #        c = Part.makeCircle(0.3,pt,tan)
    #        inf0 = c.distToShape(v0)[2][0]
    #        inf1 = c.distToShape(v1)[2][0]
    #        #print(inf0)
    #        #print(inf1)
    #        if inf0[3] == 'Edge' and inf1[3] == 'Edge':
    #            inter.add(v,(inf0[5],inf1[5]))
    edges = list()
    for tu in zip(inter.param, inter.value):
        print(tu)
        l = Part.makeLine(v0.valueAt(tu[1][0]), v1.valueAt(tu[1][1]))
        edges.append(l)

    newc0 = Part.BSplineCurve()
    pts_0 = [v0.valueAt(v[0]) for v in inter.value]
    newc0.interpolate(Points=pts_0, Parameters=inter.param)
    Part.show(newc0.toShape())

    newc1 = Part.BSplineCurve()
    pts_1 = [v1.valueAt(v[1]) for v in inter.value]
    newc1.interpolate(Points=pts_1, Parameters=inter.param)
    Part.show(newc1.toShape())

    Part.show(Part.Compound(edges))
Example #23
0
def addFaceWireToSketch(fa, w, sk):
    curves = list()
    const = list()
    pl = Part.Plane()
    for idx in range(len(w.Edges)):
        e = fa.curveOnSurface(w.Edges[idx])
        e3d = e[0].toShape(pl)
        tc = e3d.Curve.trim(e[1], e[2])
        curves.append(tc)
    o = int(sk.GeometryCount)
    sk.addGeometry(curves, False)

    # Coincident constraints
    #ar = range(len(curves))+[0]
    #for idx in range(len(curves)):
    #const.append(Sketcher.Constraint('Coincident',o+idx,2,o+ar[idx+1],1))

    for idx in range(len(curves)):
        const.append(Sketcher.Constraint('Block', o + idx))
    sk.addConstraint(const)
Example #24
0
    def testChFi2d_FilletAlgo(self):
        v = FreeCAD.Vector
        edge1 = Part.makeLine(v(0,0,0), v(0,10,0))
        edge2 = Part.makeLine(v(0,10,0), v(10,10,0))
        wire = Part.Wire([edge1, edge2])
        pln = Part.Plane()

        with self.assertRaises(TypeError):
            alg = Part.ChFi2d.FilletAlgo(pln)

        alg = Part.ChFi2d.FilletAlgo()
        with self.assertRaises(TypeError):
            alg.init()

        print (alg)
        # Test without shape
        with self.assertRaises(Base.CADKernelError):
            alg.perform(1)

        with self.assertRaises(TypeError):
            alg.perform()

        alg = Part.ChFi2d.FilletAlgo(wire, pln)
        alg.init(edge1, edge2, pln)
        alg.init(wire, pln)

        alg = Part.ChFi2d.FilletAlgo(edge1, edge2, pln)
        alg.perform(1.0)

        with self.assertRaises(TypeError):
            alg.numberOfResults()

        with self.assertRaises(TypeError):
            alg.result(1)

        self.assertEqual(alg.numberOfResults(Base.Vector(0,10,0)), 1)
        result = alg.result(Base.Vector(0,10,0))
        curve = result[0].Curve
        self.assertEqual(type(curve), Part.Circle)
        self.assertEqual(curve.Axis, pln.Axis)
        self.assertEqual(curve.Radius, 1.0)
Example #25
0
    def testShapeFix_Shape(self):
        surface = Part.Plane()
        face = surface.toShape(-1, 1, -1, 1)

        with self.assertRaises(TypeError):
            Part.ShapeFix.Shape([])

        fix = Part.ShapeFix.Shape(face)
        fix.init(face)
        print (fix)
        fix.shape()
        fix.fixSolidTool()
        fix.fixShellTool()
        fix.fixFaceTool()
        fix.fixWireTool()
        fix.fixEdgeTool()

        fix.FixSolidMode = True
        self.assertEqual(fix.FixSolidMode, True)

        fix.FixFreeShellMode = True
        self.assertEqual(fix.FixFreeShellMode, True)

        fix.FixFreeFaceMode = True
        self.assertEqual(fix.FixFreeFaceMode, True)

        fix.FixFreeWireMode = True
        self.assertEqual(fix.FixFreeWireMode, True)

        fix.FixSameParameterMode = True
        self.assertEqual(fix.FixSameParameterMode, True)

        fix.FixVertexPositionMode = True
        self.assertEqual(fix.FixVertexPositionMode, True)

        fix.FixVertexTolMode = True
        self.assertEqual(fix.FixVertexTolMode, True)

        fix.perform()
Example #26
0
def get_chord_normal_params(e1, e2, n):
    params = list()
    fp, lp = e1.ParameterRange
    chord = Part.makeLine(e1.valueAt(fp), e1.valueAt(lp))
    pts = chord.discretize(n)
    plane = Part.Plane(pts[0], chord.tangentAt(chord.FirstParameter))
    for pt in pts:
        plane.Position = pt
        p1 = e1.Curve.intersect(plane)
        p2 = e2.Curve.intersect(plane)
        print("{} - {}".format(p1, p2))
        try:
            params.append([
                e1.Curve.parameter(
                    FreeCAD.Vector(p1[0][0].X, p1[0][0].Y, p1[0][0].Z)),
                e2.Curve.parameter(
                    FreeCAD.Vector(p2[0][0].X, p2[0][0].Y, p2[0][0].Z))
            ])
            print("{}".format(params[-1]))
        except:
            _utils.warn("chord_normal compute error")
    return params
Example #27
0
def angle__():
    v, e1 = FreeCADGui.Selection.getSelectionEx(
    )[0].SubObjects  # вибрати вершину і гвинтову кромку
    e2, f = FreeCADGui.Selection.getSelectionEx(
    )[1].SubObjects  # вибрати різальну кромку і задню поверхню
    v1, v2 = e2.Vertexes
    v3 = v1 if not v.Point.isEqual(v1.Point, 1e-3) else v2  # v3 не v
    vec = e1.tangentAt(e1.parameterAt(v))  # дотична в точці
    vec = vec + v.Point  # перемістити в положення
    Part.show(Part.Point(vec).toShape())
    pl = Part.Plane(v.Point, v3.Point, vec)  # площина різання
    uv = pl.parameter(v.Point)
    vec2 = pl.normal(uv[0],
                     uv[1])  # нормаль до площини різання (0,0 або uv[0],uv[1])
    #vec2=vec2+v.Point # перемістити в положення
    #Part.show(Part.Point(vec2).toShape())

    # кут між площинами - це кут між їх нормалями !!!
    uv = f.Surface.parameter(v.Point)
    vec3 = f.Surface.normal(
        uv[0], uv[1])  # нормаль до задньої поверхні (0,0 або uv[0],uv[1])
    a = vec2.getAngle(vec3)  # кінематичний задній кут
    print np.degrees(a)
Example #28
0
    def testShapeFix_Edge(self):
        surface = Part.Plane()
        face = surface.toShape(-1, 1, -1, 1)

        with self.assertRaises(TypeError):
            Part.ShapeFix.Edge([])

        wirefix = Part.ShapeFix.Wire(face.OuterWire, face, 1e-7)
        fix = wirefix.fixEdgeTool()
        print (fix)

        fix.fixRemovePCurve(face.Edge1, face)
        fix.fixRemovePCurve(face.Edge1, face.Surface, face.Placement)
        with self.assertRaises(TypeError):
            fix.fixRemovePCurve(face)

        fix.fixRemoveCurve3d(face.Edge1)
        fix.fixAddCurve3d(face.Edge1)

        fix.fixAddPCurve(face.Edge1, face, False)
        fix.fixAddPCurve(face.Edge1, face.Surface, face.Placement, False)
        with self.assertRaises(TypeError):
            fix.fixAddPCurve(face)

        fix.fixVertexTolerance(face.Edge1)
        fix.fixVertexTolerance(face.Edge1, face)

        fix.fixReversed2d(face.Edge1, face)
        fix.fixReversed2d(face.Edge1, face.Surface, face.Placement)
        with self.assertRaises(TypeError):
            fix.fixReversed2d(face)

        fix.fixSameParameter(face.Edge1)
        fix.fixSameParameter(face.Edge1, face)
        with self.assertRaises(TypeError):
            fix.fixSameParameter(face)
Example #29
0
def make_sketch(objectslist,
                autoconstraints=False,
                addTo=None,
                delete=False,
                name="Sketch",
                radiusPrecision=-1):
    """makeSketch(objectslist,[autoconstraints],[addTo],[delete],[name],[radiusPrecision])

    Makes a Sketch objectslist with the given Draft objects.

    Parameters
    ----------
    objectlist: can be single or list of objects of Draft type objects,
        Part::Feature, Part.Shape, or mix of them.

    autoconstraints(False): if True, constraints will be automatically added to
        wire nodes, rectangles and circles.

    addTo(None) : if set to an existing sketch, geometry will be added to it
        instead of creating a new one.

    delete(False): if True, the original object will be deleted.
        If set to a string 'all' the object and all its linked object will be
        deleted

    name('Sketch'): the name for the new sketch object

    radiusPrecision(-1): If <0, disable radius constraint. If =0, add indiviaul
        radius constraint. If >0, the radius will be rounded according to this
        precision, and 'Equal' constraint will be added to curve with equal
        radius within precision.
    """

    if not App.ActiveDocument:
        App.Console.PrintError("No active document. Aborting\n")
        return

    import Part
    from Sketcher import Constraint
    import Sketcher

    StartPoint = 1
    EndPoint = 2
    MiddlePoint = 3
    deletable = None

    if not isinstance(objectslist, (list, tuple)):
        objectslist = [objectslist]
    for obj in objectslist:
        if isinstance(obj, Part.Shape):
            shape = obj
        elif not hasattr(obj, 'Shape'):
            App.Console.PrintError(translate("draft", "not shape found"))
            return None
        else:
            shape = obj.Shape
        if not DraftGeomUtils.isPlanar(shape):
            App.Console.PrintError(
                translate("draft", "All Shapes must be co-planar"))
            return None
    if addTo:
        nobj = addTo
    else:
        nobj = App.ActiveDocument.addObject("Sketcher::SketchObject", name)
        deletable = nobj
        if App.GuiUp:
            nobj.ViewObject.Autoconstraints = False

    # Collect constraints and add in one go to improve performance
    constraints = []
    radiuses = {}

    def addRadiusConstraint(edge):
        try:
            if radiusPrecision < 0:
                return
            if radiusPrecision == 0:
                constraints.append(
                    Constraint('Radius', nobj.GeometryCount - 1,
                               edge.Curve.Radius))
                return
            r = round(edge.Curve.Radius, radiusPrecision)
            constraints.append(
                Constraint('Equal', radiuses[r], nobj.GeometryCount - 1))
        except KeyError:
            radiuses[r] = nobj.GeometryCount - 1
            constraints.append(Constraint('Radius', nobj.GeometryCount - 1, r))
        except AttributeError:
            pass

    def convertBezier(edge):
        if DraftGeomUtils.geomType(edge) == "BezierCurve":
            return (edge.Curve.toBSpline(edge.FirstParameter,
                                         edge.LastParameter).toShape())
        else:
            return (edge)

    rotation = None
    for obj in objectslist:
        ok = False
        tp = utils.get_type(obj)
        if tp in ["Circle", "Ellipse"]:
            if obj.Shape.Edges:
                if rotation is None:
                    rotation = obj.Placement.Rotation
                edge = obj.Shape.Edges[0]
                if len(edge.Vertexes) == 1:
                    newEdge = DraftGeomUtils.orientEdge(edge)
                    nobj.addGeometry(newEdge)
                else:
                    # make new ArcOfCircle
                    circle = DraftGeomUtils.orientEdge(edge)
                    angle = edge.Placement.Rotation.Angle
                    axis = edge.Placement.Rotation.Axis
                    circle.Center = DraftVecUtils.rotate(
                        edge.Curve.Center, -angle, axis)
                    first = math.radians(obj.FirstAngle)
                    last = math.radians(obj.LastAngle)
                    arc = Part.ArcOfCircle(circle, first, last)
                    nobj.addGeometry(arc)
                addRadiusConstraint(edge)
                ok = True
        elif tp == "Rectangle":
            if rotation is None:
                rotation = obj.Placement.Rotation
            if obj.FilletRadius.Value == 0:
                for edge in obj.Shape.Edges:
                    nobj.addGeometry(DraftGeomUtils.orientEdge(edge))
                if autoconstraints:
                    last = nobj.GeometryCount - 1
                    segs = [last - 3, last - 2, last - 1, last]
                    if obj.Placement.Rotation.Q == (0, 0, 0, 1):
                        constraints.append(
                            Constraint("Coincident", last - 3, EndPoint,
                                       last - 2, StartPoint))
                        constraints.append(
                            Constraint("Coincident", last - 2, EndPoint,
                                       last - 1, StartPoint))
                        constraints.append(
                            Constraint("Coincident", last - 1, EndPoint, last,
                                       StartPoint))
                        constraints.append(
                            Constraint("Coincident", last, EndPoint, last - 3,
                                       StartPoint))
                    constraints.append(Constraint("Horizontal", last - 3))
                    constraints.append(Constraint("Vertical", last - 2))
                    constraints.append(Constraint("Horizontal", last - 1))
                    constraints.append(Constraint("Vertical", last))
                ok = True
        elif tp in ["Wire", "Polygon"]:
            if obj.FilletRadius.Value == 0:
                closed = False
                if tp == "Polygon":
                    closed = True
                elif hasattr(obj, "Closed"):
                    closed = obj.Closed

                if obj.Shape.Edges:
                    if (len(obj.Shape.Vertexes) < 3):
                        e = obj.Shape.Edges[0]
                        nobj.addGeometry(
                            Part.LineSegment(e.Curve, e.FirstParameter,
                                             e.LastParameter))
                    else:
                        # Use the first three points to make a working plane. We've already
                        # checked to make sure everything is coplanar
                        plane = Part.Plane(
                            *[i.Point for i in obj.Shape.Vertexes[:3]])
                        normal = plane.Axis
                        if rotation is None:
                            axis = App.Vector(0, 0, 1).cross(normal)
                            angle = DraftVecUtils.angle(
                                normal, App.Vector(0, 0, 1)) * App.Units.Radian
                            rotation = App.Rotation(axis, angle)
                        for edge in obj.Shape.Edges:
                            # edge.rotate(App.Vector(0,0,0), rotAxis, rotAngle)
                            edge = DraftGeomUtils.orientEdge(edge, normal)
                            nobj.addGeometry(edge)
                        if autoconstraints:
                            last = nobj.GeometryCount
                            segs = list(
                                range(last - len(obj.Shape.Edges), last - 1))
                            for seg in segs:
                                constraints.append(
                                    Constraint("Coincident", seg, EndPoint,
                                               seg + 1, StartPoint))
                                if DraftGeomUtils.isAligned(
                                        nobj.Geometry[seg], "x"):
                                    constraints.append(
                                        Constraint("Vertical", seg))
                                elif DraftGeomUtils.isAligned(
                                        nobj.Geometry[seg], "y"):
                                    constraints.append(
                                        Constraint("Horizontal", seg))
                            if closed:
                                constraints.append(
                                    Constraint("Coincident", last - 1,
                                               EndPoint, segs[0], StartPoint))
                    ok = True
        elif tp == "BSpline":
            if obj.Shape.Edges:
                nobj.addGeometry(obj.Shape.Edges[0].Curve)
                nobj.exposeInternalGeometry(nobj.GeometryCount - 1)
                ok = True
        elif tp == "BezCurve":
            if obj.Shape.Edges:
                bez = obj.Shape.Edges[0].Curve
                bsp = bez.toBSpline(bez.FirstParameter, bez.LastParameter)
                nobj.addGeometry(bsp)
                nobj.exposeInternalGeometry(nobj.GeometryCount - 1)
                ok = True
        elif tp == 'Shape' or hasattr(obj, 'Shape'):
            shape = obj if tp == 'Shape' else obj.Shape

            if not DraftGeomUtils.isPlanar(shape):
                App.Console.PrintError(
                    translate(
                        "draft",
                        "The given object is not planar and cannot be converted into a sketch."
                    ))
                return None
            if rotation is None:
                #rotation = obj.Placement.Rotation
                norm = DraftGeomUtils.getNormal(shape)
                if norm:
                    rotation = App.Rotation(App.Vector(0, 0, 1), norm)
                else:
                    App.Console.PrintWarning(
                        translate(
                            "draft",
                            "Unable to guess the normal direction of this object"
                        ))
                    rotation = App.Rotation()
                    norm = obj.Placement.Rotation.Axis
            if not shape.Wires:
                for e in shape.Edges:
                    # unconnected edges
                    newedge = convertBezier(e)
                    nobj.addGeometry(
                        DraftGeomUtils.orientEdge(newedge, norm,
                                                  make_arc=True))
                    addRadiusConstraint(newedge)

            # if not addTo:
            # nobj.Placement.Rotation = DraftGeomUtils.calculatePlacement(shape).Rotation

            if autoconstraints:
                for wire in shape.Wires:
                    last_count = nobj.GeometryCount
                    edges = wire.OrderedEdges
                    for edge in edges:
                        newedge = convertBezier(edge)
                        nobj.addGeometry(
                            DraftGeomUtils.orientEdge(newedge,
                                                      norm,
                                                      make_arc=True))
                        addRadiusConstraint(newedge)
                    for i, g in enumerate(nobj.Geometry[last_count:]):
                        if edges[i].Closed:
                            continue
                        seg = last_count + i

                        if DraftGeomUtils.isAligned(g, "x"):
                            constraints.append(Constraint("Vertical", seg))
                        elif DraftGeomUtils.isAligned(g, "y"):
                            constraints.append(Constraint("Horizontal", seg))

                        if seg == nobj.GeometryCount - 1:
                            if not wire.isClosed():
                                break
                            g2 = nobj.Geometry[last_count]
                            seg2 = last_count
                        else:
                            seg2 = seg + 1
                            g2 = nobj.Geometry[seg2]

                        end1 = g.value(g.LastParameter)
                        start2 = g2.value(g2.FirstParameter)
                        if DraftVecUtils.equals(end1, start2):
                            constraints.append(
                                Constraint("Coincident", seg, EndPoint, seg2,
                                           StartPoint))
                            continue
                        end2 = g2.value(g2.LastParameter)
                        start1 = g.value(g.FirstParameter)
                        if DraftVecUtils.equals(end2, start1):
                            constraints.append(
                                Constraint("Coincident", seg, StartPoint, seg2,
                                           EndPoint))
                        elif DraftVecUtils.equals(start1, start2):
                            constraints.append(
                                Constraint("Coincident", seg, StartPoint, seg2,
                                           StartPoint))
                        elif DraftVecUtils.equals(end1, end2):
                            constraints.append(
                                Constraint("Coincident", seg, EndPoint, seg2,
                                           EndPoint))
            else:
                for wire in shape.Wires:
                    for edge in wire.OrderedEdges:
                        newedge = convertBezier(edge)
                        nobj.addGeometry(
                            DraftGeomUtils.orientEdge(newedge,
                                                      norm,
                                                      make_arc=True))
            ok = True
        gui_utils.format_object(nobj, obj)
        if ok and delete and hasattr(obj, 'Shape'):
            doc = obj.Document

            def delObj(obj):
                if obj.InList:
                    App.Console.PrintWarning(
                        translate(
                            "draft", "Cannot delete object {} with dependency".
                            format(obj.Label)) + "\n")
                else:
                    doc.removeObject(obj.Name)

            try:
                if delete == 'all':
                    objs = [obj]
                    while objs:
                        obj = objs[0]
                        objs = objs[1:] + obj.OutList
                        delObj(obj)
                else:
                    delObj(obj)
            except Exception as ex:
                App.Console.PrintWarning(
                    translate(
                        "draft", "Failed to delete object {}: {}".format(
                            obj.Label, ex)) + "\n")
    if rotation:
        nobj.Placement.Rotation = rotation
    else:
        print("-----error!!! rotation is still None...")
    nobj.addConstraint(constraints)

    return nobj
Example #30
0
def getElementShape(obj, tp=None, transform=False, noElementMap=True):
    if not isinstance(obj, (tuple, list)):
        shape = obj
    else:
        sub = obj[1]
        shape, mat, sobj = Part.getShape(obj[0],
                                         subname=sub,
                                         needSubElement=True,
                                         retType=2,
                                         transform=transform,
                                         noElementMap=noElementMap)
        if not sobj:
            logger.trace('no sub object {}', obj, frame=1)
            return
        if sobj.isDerivedFrom('App::Line'):
            if tp not in (None, Part.Shape, Part.Edge):
                logger.trace('wrong type of shape {}', obj)
                return
            size = sobj.ViewObject.Size
            shape = Part.makeLine(FreeCAD.Vector(-size, 0, 0),
                                  FreeCAD.Vector(size, 0, 0))
            shape.transformShape(mat, False, True)
        elif sobj.isDerivedFrom('App::Plane'):
            if tp not in (None, Part.Shape, Part.Face):
                logger.trace('wrong type of shape {}', obj)
                return
            size = sobj.ViewObject.Size
            shape = Part.makePlane(size * 2, size * 2,
                                   FreeCAD.Vector(-size, -size, 0))
            shape.transformShape(mat, False, True)
        elif sobj.isDerivedFrom('App::Placement'):
            sub = sub.split('.')[-1]
            dmap = {
                '': (0, 0, 1),
                'Origin': (0, 0, 1),
                'Z-Axis': (0, 0, 1),
                'XY-Plane': (0, 0, -1),
                'X-Axis': (1, 0, 0),
                'YZ-Plane': (-1, 0, 0),
                'Y-Axis': (0, 1, 0),
                'XZ-Plane': (0, -1, 0)
            }
            shape = Part.Face(
                Part.Plane(FreeCAD.Vector(), FreeCAD.Vector(*dmap[sub])))
            shape.transformShape(mat, False, True)
        elif shape.isNull():
            logger.trace('no shape {}', obj)
            return

    if not isinstance(shape, Part.Shape) or shape.isNull():
        logger.trace('null shape {}', obj)
        return

    if not tp or isinstance(shape, tp):
        return shape
    elif isinstance(shape, (Part.Vertex, Part.Edge, Part.Face)):
        logger.trace('wrong shape type {}', obj)
        return
    elif tp is Part.Vertex:
        if shape.countElement('Edge'):
            return
        if shape.countElement('Vertex') == 1:
            return shape.Vertex1
    elif tp is Part.Edge:
        if shape.countElement('Face'):
            return
        if shape.countElement('Edge') == 1:
            return shape.Edge1
    elif tp is Part.Face:
        if shape.countElement('Face') == 1:
            return shape.Face1
    else:
        logger.trace('wrong shape type {}', obj)