Example #1
0
 def binormalFace(self, samp, dist, tol=1e-5, sym=False):
     face = None
     if sym:
         dist /=2.0
     ran = self.lastParameter - self.firstParameter
     pts = list()
     pars = list()
     for i in range(samp):
         t = self.firstParameter + float(i) * ran / (samp-1)
         pts.append(self.valueAt(t).add(self.binormalAt(t)*float(dist)))
         pars.append(t)
     #if self._closed:
         #pts = pts[:-1]
     bs = Part.BSplineCurve()
     bs.approximate(Points = pts, Parameters = pars, DegMin = 3, DegMax = 7, Tolerance = tol)
     if sym:
         pts = list()
         pars = list()
         for i in range(samp):
             t = self.firstParameter + float(i) * ran / (samp-1)
             pts.append(self.valueAt(t).sub(self.binormalAt(t)*float(dist)))
             pars.append(t)
         #if self._closed:
             #pts = pts[:-1]
         bs2 = Part.BSplineCurve()
         bs2.approximate(Points = pts, Parameters = pars, DegMin = 3, DegMax = 7, Tolerance = tol)
         face = Part.makeRuledSurface(bs2.toShape(), bs.toShape())
     else:
         face = Part.makeRuledSurface(self.edgeOnFace, bs.toShape())
     if self._closed:
         surf = face.Surface.copy()
         surf.setUPeriodic()
         face = surf.toShape()
     #nf = face.transformGeometry(self.face.Placement.toMatrix())
     return(face.transformGeometry(self.face.Placement.toMatrix()))
Example #2
0
def ruled_surface(e1,e2):
    """ creates a ruled surface between 2 edges, with automatic orientation."""
    # Automatic orientation
    # /src/Mod/Part/App/PartFeatures.cpp#171
    p1 = e1.valueAt(e1.FirstParameter)
    p2 = e1.valueAt(e1.LastParameter)
    p3 = e2.valueAt(e2.FirstParameter)
    p4 = e2.valueAt(e2.LastParameter)
    if e1.Orientation == 'Reversed':
        p = p1
        p1 = p2
        p2 = p
    if e2.Orientation == 'Reversed':
        p = p3
        p3 = p4
        p4 = p
    v1 = p2 - p1
    v2 = p3 - p1
    n1 = v1.cross(v2)
    v3 = p3 - p4
    v4 = p2 - p4
    n2 = v3.cross(v4)
    if (n1.dot(n2) < 0):
        e = e2.copy()
        e.reverse()
        return(Part.makeRuledSurface(e1,e))
    else:
        return(Part.makeRuledSurface(e1,e2))
Example #3
0
def ruled_surface(e1, e2):
    """ creates a ruled surface between 2 edges, with automatic orientation."""
    # Automatic orientation
    # /src/Mod/Part/App/PartFeatures.cpp#171
    p1 = e1.valueAt(e1.FirstParameter)
    p2 = e1.valueAt(e1.LastParameter)
    p3 = e2.valueAt(e2.FirstParameter)
    p4 = e2.valueAt(e2.LastParameter)
    if e1.Orientation == 'Reversed':
        p = p1
        p1 = p2
        p2 = p
    if e2.Orientation == 'Reversed':
        p = p3
        p3 = p4
        p4 = p
    v1 = p2 - p1
    v2 = p3 - p1
    n1 = v1.cross(v2)
    v3 = p3 - p4
    v4 = p2 - p4
    n2 = v3.cross(v4)
    if (n1.dot(n2) < 0):
        e = e2.copy()
        e.reverse()
        return (Part.makeRuledSurface(e1, e))
    else:
        return (Part.makeRuledSurface(e1, e2))
Example #4
0
 def binormalFace(self, samp, dist, tol=1e-5, sym=False):
     face = None
     if sym:
         dist /=2.0
     ran = self.lastParameter - self.firstParameter
     pts = list()
     pars = list()
     for i in range(samp):
         t = self.firstParameter + float(i) * ran / (samp-1)
         pts.append(self.valueAt(t).add(self.binormalAt(t)*float(dist)))
         pars.append(t)
     #if self._closed:
         #pts = pts[:-1]
     bs = Part.BSplineCurve()
     bs.approximate(Points = pts, Parameters = pars, DegMin = 3, DegMax = 7, Tolerance = tol)
     if sym:
         pts = list()
         pars = list()
         for i in range(samp):
             t = self.firstParameter + float(i) * ran / (samp-1)
             pts.append(self.valueAt(t).sub(self.binormalAt(t)*float(dist)))
             pars.append(t)
         #if self._closed:
             #pts = pts[:-1]
         bs2 = Part.BSplineCurve()
         bs2.approximate(Points = pts, Parameters = pars, DegMin = 3, DegMax = 7, Tolerance = tol)
         face = Part.makeRuledSurface(bs2.toShape(), bs.toShape())
     else:
         face = Part.makeRuledSurface(self.edgeOnFace, bs.toShape())
     if self._closed:
         surf = face.Surface.copy()
         surf.setUPeriodic()
         face = surf.toShape()
     #nf = face.transformGeometry(self.face.Placement.toMatrix())
     return(face.transformGeometry(self.face.Placement.toMatrix()))
Example #5
0
def ruled_surface(e1, e2):
    """creates a ruled surface between 2 edges, with automatic orientation."""
    if not same_direction(e1, e2):
        e = e2.copy()
        e.reverse()
        return Part.makeRuledSurface(e1, e)
    else:
        return Part.makeRuledSurface(e1, e2)
Example #6
0
 def execute(self, obj):
     c1, c2 = self.get_curves(obj)
     nc1, nc2 = rp.reparametrize(c1, c2, num=obj.Samples, smooth_start=obj.SmoothingFactorStart, smooth_end=obj.SmoothingFactorEnd, method=obj.Method )
     #com = Part.Compound([nc1.toShape(), nc2.toShape()])
     rs = Part.makeRuledSurface(nc1.toShape(), nc2.toShape())
     if isinstance(rs, Part.Face) and rs.isValid():
         obj.Shape = rs
Example #7
0
 def makeRuledSurface(cls, edgeOrWire1, edgeOrWire2, dist=None):
     """
     'makeRuledSurface(Edge|Wire,Edge|Wire) -- Make a ruled surface
     Create a ruled surface out of two edges or wires. If wires are used then
     these must have the same
     """
     return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.wrapped, edgeOrWire2.wrapped))
Example #8
0
 def ruledSurface(self):
     if isinstance(self.edge1,Part.Edge) and isinstance(self.edge2,Part.Edge):
         self.ruled = Part.makeRuledSurface(self.edge1, self.edge2)
         self.rail1 = self.ruled.Edges[0]
         self.rail2 = self.ruled.Edges[2]
         self.u0 = self.ruled.ParameterRange[0]
         self.u1 = self.ruled.ParameterRange[1]
 def makeRuledSurface(cls, edgeOrWire1, edgeOrWire2, dist=None):
     """
     'makeRuledSurface(Edge|Wire,Edge|Wire) -- Make a ruled surface
     Create a ruled surface out of two edges or wires. If wires are used then
     these must have the same
     """
     return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.obj, edgeOrWire2.obj, dist))
Example #10
0
def flat_cylinder_surface(face, in_place=False):
    """
    flat_face = flat_cylinder_surface(face, in_place=False)
    Creates a flat nurbs surface from input cylindrical face, with same parametrization.
    If in_place is True, the surface is located at the seam edge of the face.
    """
    u0, u1, v0, v1 = get_finite_surface_bounds(face)
    c1 = face.Surface.uIso(u0)  # seam line
    e1 = c1.toShape(v0, v1)
    l1 = e1.Length
    c2 = face.Surface.vIso(v0)  # circle
    e2 = c2.toShape(u0, u1)
    l2 = e2.Length
    if in_place:
        t1 = c2.tangent(c2.FirstParameter)[0]
        e3 = e1.copy()
        e3.translate(t1 * l2)
        rs = Part.makeRuledSurface(e1, e3)
        bs = rs.Surface
        bs.exchangeUV()
    else:
        bs = Part.BSplineSurface()
        bs.setPole(1, 1, vec3(v0, 0, 0))
        bs.setPole(1, 2, vec3(v1, 0, 0))
        bs.setPole(2, 1, vec3(v0, l2, 0))
        bs.setPole(2, 2, vec3(v1, l2, 0))
    bs.setUKnots([0, 2 * pi])
    bs.setVKnots([v0, v1])
    return bs
Example #11
0
def flat_cone_surface(face, in_place=False):
    """
    flat_face = flat_cone_surface(face, in_place=False)
    Creates a flat nurbs surface from input conical face, with same parametrization.
    If in_place is True, the surface is located at the seam edge of the face.
    """
    u0, u1, v0, v1 = get_finite_surface_bounds(face)
    seam = face.Surface.uIso(u0)
    p1 = seam.value(v0)
    p2 = seam.value(v1)
    radius1 = face.Surface.Apex.distanceToPoint(p1)
    radius2 = face.Surface.Apex.distanceToPoint(p2)
    t = seam.tangent(v0)[0]
    normal = -t.cross(face.Surface.Axis.cross(t))
    c1 = Part.Circle(face.Surface.Apex, normal, radius1)
    c2 = Part.Circle(face.Surface.Apex, normal, radius2)
    ci1 = face.Surface.vIso(v0)
    ci2 = face.Surface.vIso(v1)
    fp1 = c1.parameter(p1)
    fp2 = c2.parameter(p2)
    lp1 = c1.parameterAtDistance(ci1.length(), fp1)
    lp2 = c2.parameterAtDistance(ci2.length(), fp2)
    if not in_place:
        c1 = Part.Circle(vec3(0, 0, 0), vec3(0, 0, 1), radius1)
        c2 = Part.Circle(vec3(0, 0, 0), vec3(0, 0, 1), radius2)
    else:
        c1.Axis = -c1.Axis
        c2.Axis = -c2.Axis
    ce1 = c1.toShape(fp1, lp1)
    ce2 = c2.toShape(fp2, lp2)
    rs = Part.makeRuledSurface(ce1, ce2)
    bs = rs.Surface
    bs.setUKnots([0, 2 * pi])
    bs.setVKnots([v0, v1])
    return bs
Example #12
0
 def ruledSurface(self):
     if isinstance(self.edge1, Part.Edge) and isinstance(
             self.edge2, Part.Edge):
         self.ruled = Part.makeRuledSurface(self.edge1, self.edge2)
         self.rail1 = self.ruled.Edges[0]
         self.rail2 = self.ruled.Edges[2]
         self.u0 = self.ruled.ParameterRange[0]
         self.u1 = self.ruled.ParameterRange[1]
Example #13
0
    def extrudeLinearWithRotation(cls, outerWire, innerWires, vecCenter,
                                  vecNormal, angleDegrees):
        """
            Creates a 'twisted prism' by extruding, while simultaneously rotating around the extrusion vector.

            Though the signature may appear to be similar enough to extrudeLinear to merit combining them, the
            construction methods used here are different enough that they should be separate.

            At a high level, the steps followed are:
            (1) accept a set of wires
            (2) create another set of wires like this one, but which are transformed and rotated
            (3) create a ruledSurface between the sets of wires
            (4) create a shell and compute the resulting object

            :param outerWire: the outermost wire, a cad.Wire
            :param innerWires: a list of inner wires, a list of cad.Wire
            :param vecCenter: the center point about which to rotate.  the axis of rotation is defined by
                   vecNormal, located at vecCenter. ( a cad.Vector )
            :param vecNormal: a vector along which to extrude the wires ( a cad.Vector )
            :param angleDegrees: the angle to rotate through while extruding
            :return: a cad.Solid object
        """

        # from this point down we are dealing with FreeCAD wires not cad.wires
        startWires = [outerWire.wrapped] + [i.wrapped for i in innerWires]
        endWires = []
        p1 = vecCenter.wrapped
        p2 = vecCenter.add(vecNormal).wrapped

        # make translated and rotated copy of each wire
        for w in startWires:
            w2 = w.copy()
            w2.translate(vecNormal.wrapped)
            w2.rotate(p1, p2, angleDegrees)
            endWires.append(w2)

        # make a ruled surface for each set of wires
        sides = []
        for w1, w2 in zip(startWires, endWires):
            rs = FreeCADPart.makeRuledSurface(w1, w2)
            sides.append(rs)

        #make faces for the top and bottom
        startFace = FreeCADPart.Face(startWires)
        endFace = FreeCADPart.Face(endWires)
        startFace.validate()
        endFace.validate()

        #collect all the faces from the sides
        faceList = [startFace]
        for s in sides:
            faceList.extend(s.Faces)
        faceList.append(endFace)

        shell = FreeCADPart.makeShell(faceList)
        solid = FreeCADPart.makeSolid(shell)
        return Shape.cast(solid)
Example #14
0
    def extrudeLinearWithRotation(cls, outerWire, innerWires, vecCenter, vecNormal, angleDegrees):
        """
            Creates a 'twisted prism' by extruding, while simultaneously rotating around the extrusion vector.

            Though the signature may appear to be similar enough to extrudeLinear to merit combining them, the
            construction methods used here are different enough that they should be separate.

            At a high level, the steps followed are:
            (1) accept a set of wires
            (2) create another set of wires like this one, but which are transformed and rotated
            (3) create a ruledSurface between the sets of wires
            (4) create a shell and compute the resulting object

            :param outerWire: the outermost wire, a cad.Wire
            :param innerWires: a list of inner wires, a list of cad.Wire
            :param vecCenter: the center point about which to rotate.  the axis of rotation is defined by
                   vecNormal, located at vecCenter. ( a cad.Vector )
            :param vecNormal: a vector along which to extrude the wires ( a cad.Vector )
            :param angleDegrees: the angle to rotate through while extruding
            :return: a cad.Solid object
        """

        # from this point down we are dealing with FreeCAD wires not cad.wires
        startWires = [outerWire.wrapped] + [i.wrapped for i in innerWires]
        endWires = []
        p1 = vecCenter.wrapped
        p2 = vecCenter.add(vecNormal).wrapped

        # make translated and rotated copy of each wire
        for w in startWires:
            w2 = w.copy()
            w2.translate(vecNormal.wrapped)
            w2.rotate(p1, p2, angleDegrees)
            endWires.append(w2)

        # make a ruled surface for each set of wires
        sides = []
        for w1, w2 in zip(startWires, endWires):
            rs = FreeCADPart.makeRuledSurface(w1, w2)
            sides.append(rs)

        #make faces for the top and bottom
        startFace = FreeCADPart.Face(startWires)
        endFace = FreeCADPart.Face(endWires)
        startFace.validate()
        endFace.validate()

        #collect all the faces from the sides
        faceList = [startFace]
        for s in sides:
            faceList.extend(s.Faces)
        faceList.append(endFace)

        shell = FreeCADPart.makeShell(faceList)
        solid = FreeCADPart.makeSolid(shell)
        return Shape.cast(solid)
Example #15
0
 def execute(self, obj):
     pl = obj.Placement
     c1 = Part.Circle()
     c1.Radius = obj.OutDiameter.Value
     c2 = Part.Circle()
     c2.Radius = obj.OutDiameter.Value - 2 * obj.Thickness.Value
     cs1 = c1.toShape()
     cs2 = c2.toShape()
     p = Part.makeRuledSurface(cs2, cs1)
     obj.Shape = p
     obj.Placement = pl
Example #16
0
 def execute(self,obj):
     pl = obj.Placement
     c1=Part.Circle()
     c1.Radius=obj.OutDiameter.Value
     c2=Part.Circle()
     c2.Radius=obj.OutDiameter.Value-2*obj.Thickness.Value
     cs1=c1.toShape()
     cs2=c2.toShape()
     p=Part.makeRuledSurface(cs2,cs1)
     obj.Shape = p
     obj.Placement = pl
Example #17
0
 def execute(self, obj):
     import Part
     pl = obj.Placement
     c1 = Part.Circle()
     c1.Radius = obj.OutDiameter.Value / 2
     c2 = Part.Circle()
     c2.Radius = obj.OutDiameter.Value / 2 - obj.Thickness.Value
     cs1 = c1.toShape()
     cs2 = c2.toShape()
     p = Part.makeRuledSurface(cs2, cs1)
     p.reverse()
     obj.Shape = p
     obj.Placement = pl
Example #18
0
 def execute(self,obj):
     import Part
     pl = obj.Placement
     c1=Part.Circle()
     c1.Radius=obj.OutDiameter.Value/2
     c2=Part.Circle()
     c2.Radius=obj.OutDiameter.Value/2-obj.Thickness.Value
     cs1=c1.toShape()
     cs2=c2.toShape()
     p=Part.makeRuledSurface(cs2,cs1)
     p.reverse()
     obj.Shape = p
     obj.Placement = pl
Example #19
0
    def make_solid(self, face1, face2):
        if self.flip_face1:
            face1.face.reverse()
        if self.flip_face2:
            face2.face.reverse()
        edges1 = face1.face.OuterWire.Edges
        edges2 = face2.face.OuterWire.Edges
        n1 = len(edges1)
        n2 = len(edges2)
        if n1 != n2:
            raise Exception(
                f"Faces have different number of edges: {n1} != {n2}")

        fc_sides = []
        sv_sides = []

        edges1 = reverse_edges(edges1, reverse=self.reverse1, flip=self.flip1)
        edges2 = reverse_edges(edges2, reverse=self.reverse2, flip=self.flip2)
        edges1, edges2 = reorder(edges1, edges2)

        for edge1, edge2 in zip(edges1, edges2):
            side = Part.makeRuledSurface(edge1, edge2)
            sv_side = SvFreeCadNurbsSurface(side.Surface, face=side)
            fc_sides.append(side)
            sv_sides.append(sv_side)

        shell = Part.makeShell([face1.face, face2.face] + fc_sides)
        lst = [face1.face, face2.face] + fc_sides
        sh = lst[0].fuse(lst[1:])
        solid = Part.makeSolid(sh)
        if not solid.isValid():
            self.debug("Resulting solid is not valid!")
            if not solid.fix(self.precision, self.precision, self.precision):
                message = "Solid is not valid, and is not possible to fix"
                if self.validate:
                    raise Exception(message)
                else:
                    self.error(message)
        return solid
Example #20
0
            Base.Vector(x[0], x[1], x[2])
            for x in numpy.vstack((intradosPtsInterp[LEidx::-1],
                                   extradosPtsInterp[1:LEidx]))
        ]))
    TELines.append(
        Part.makePolygon([
            intradosInterp.Vertexes[-1].Point,
            extradosInterp.Vertexes[-1].Point
        ]))

print("Creating surfaces")
### LE SURFACE

LESurfaces = []
for i in range(2, len(LELines[:-1])):  #Start from airfoils, not cylinders
    LESurfaces.append(Part.makeRuledSurface(LELines[i], LELines[i + 1]))

LE = Part.Compound(LESurfaces)
#LE=Part.makeLoft(LELines)

Part.show(LE)

##### EXTRADOS SURFACE
extradosSurfaces = []
for i in range(len(extradosLine[:-1])):
    extradosSurfaces.append(
        Part.makeRuledSurface(extradosLine[i], extradosLine[i + 1]))

extrados = Part.Compound(extradosSurfaces)
#extrados=Part.makeLoft(extradosLine)
#Part.show(extrados)
Example #21
0
    def accept(self):
        ActiveDocument = FreeCAD.ActiveDocument
        filename = self.form.filename.text()
        symmetric = self.form.symmetric.isChecked()
        chine_count = self.form.chine_count.value()
        keel_width = [self.form.keel_width.value()]

        if not os.path.exists(filename):
            return

        def tonum(x):
            if isinstance(x, float):
                return x
            try:
                x = x.strip()
                return float(x)
            except:
                return None

        def tonumarr(x):
            return [tonum(y) for y in x]

        with open(filename, 'r') as f:
            lines = [x.split(',')[1:] for x in f]

        station_names = lines[0]
        x = lines[1]
        sheer_height = lines[2]
        sheer_x = lines[3]
        # Apart from the chines, there are six rows:
        # - Station names
        # - Station distance from stern
        # - Sheer height
        # - Sheer x
        # - Rabbet height
        # - Rabbet x
        # - Keel height
        # - Keel x
        # - Sheer half-width
        # Each height or width row has a second row below it.  If a column of this second row
        # is not empty, it means that the corresponding poiot is a corner point, rather than
        # a smooth B-spline point.
        chine_height = lines[4:2 * chine_count + 4:2]
        chine_x = lines[5:2 * chine_count + 5:2]
        rabbet_height = lines[2 * chine_count + 4]
        rabbet_x = lines[2 * chine_count + 5]
        keel_height = lines[2 * chine_count + 6]
        keel_x = lines[2 * chine_count + 7]
        sheer_width = lines[2 * chine_count + 8]
        chine_width = lines[2 * chine_count + 9:]

        print('\n'.join(str(x) for x in [keel_height, keel_x]))

        print(keel_width)
        keel_width = keel_width * len(station_names)
        print(keel_width)

        def end_tangent(pt, pt1, t):
            diff = pt - pt1
            angle = diff.getAngle(t)
            axis = diff.cross(t)
            rot = FreeCAD.Rotation(axis, -angle)
            return rot.multVec(-diff) * (t.Length / diff.Length)

        def trivial_tangent(pt1, pt2):
            return pt1 - pt2

        def middle_tangent(pt_prev, pt, pt_next):
            a = pt_prev - pt
            b = pt_next - pt
            tangent = (a + b) / 2
            axis = a.cross(b)
            rot = FreeCAD.Rotation(axis, 90)
            return rot.multVec(tangent)

        def tangents(pts, corner):
            assert len(pts) == len(corner)
            assert len(pts) > 1
            if len(pts) == 2:
                return [pts[1] - pts[0], pts[0] - pts[1]]

            calc_tangents = [None] * len(pts)
            non_none_pts = (item for item in pts if item is not None)
            first = next(non_none_pts)
            second = next(non_none_pts)
            prev = first
            prev_tangent = None
            last_pt_index = next(
                reversed([
                    index for index, item in enumerate(pts) if item is not None
                ]))
            for ii in range(1, last_pt_index - 1):
                if pts[ii] is None:
                    continue
                pt = pts[ii]
                nxt = next(item for item in pts[ii + 1:] if item is not None)
                calc_tangents[ii] = middle_tangent(prev, pt, nxt)
                prev = pt
                prev_tangent = calc_tangents[ii]

            second_tangent = [
                t for pt, t in zip(pts, calc_tangents) if pt is not None
            ][1]
            calc_tangents[0] = end_tangent(first, second, second_tangent)
            calc_tangents[last_pt_index] = end_tangent(pts[last_pt_index],
                                                       prev, prev_tangent)
            return calc_tangents

        def make_part(x, y, z, corner):
            print('Part')
            x, y, z = tonumarr(x), tonumarr(y), tonumarr(z)
            print(x, y, z)
            vertices = [
                FreeCAD.Vector(a, b, c) if
                (a is not None and b is not None and c is not None) else None
                for a, b, c in zip(x, y, z)
            ]
            print(vertices)
            segments = []
            segment = []
            segment_corners = []
            overall_tangents = tangents(vertices, corner)
            first_tangent = None
            for vertex, c, t in zip(vertices, corner, overall_tangents):
                if vertex is None:
                    continue
                segment.append(vertex)
                segment_corners.append(c)
                if c is not None and c == 'x':
                    curve = Part.BSplineCurve()
                    ts = tangents(segment, segment_corners)
                    if first_tangent:
                        ts[0] = first_tangent
                    curve.interpolate(segment, Tangents=ts)
                    segments.append(curve)
                    segment = [vertex]
                    segment_corners = [c]
                    first_tangent = None
                if c is not None and c == 'y':
                    curve = Part.BSplineCurve()
                    ts = tangents(segment, segment_corners)
                    ts[-1] = t
                    if first_tangent:
                        ts[0] = first_tangent
                    curve.interpolate(segment, Tangents=ts)
                    segments.append(curve)
                    segment = [vertex]
                    segment_corners = [c]
                    first_tangent = t
            if (len(segment) > 0):
                curve = Part.BSplineCurve()
                curve.interpolate(segment)
                segments.append(curve)
            print('\n'.join(str(s) for s in segments))
            shape = Part.makeCompound([x.toShape() for x in segments])
            part = ActiveDocument.addObject('Part::Feature', 'Feature')
            part.Shape = shape
            return part

        hull = ActiveDocument.addObject("App::Part", "Hull")
        ActiveDocument.Tip = hull

        print(', '.join(
            str(x)
            for x in (x[0], sheer_width[0], sheer_height[0], sheer_x[0])))
        sheer = make_part(x, sheer_width, sheer_height, sheer_x)
        chines = [
            make_part(x, y, z, c)
            for y, z, c in zip(chine_width, chine_height, chine_x)
        ]
        rabbet = make_part(x, keel_width, rabbet_height, rabbet_x)
        keel = make_part(x, keel_width, keel_height, keel_x)

        sheer.Label = "Sheer"
        hull.addObject(sheer)
        for i, chine in enumerate(chines):
            chine.Label = "Chine{}".format(i)
            hull.addObject(chine)
        rabbet.Label = "Rabbet"
        hull.addObject(rabbet)
        keel.Label = "Keel"
        hull.addObject(keel)
        surf = Part.makeRuledSurface(sheer.Shape, chine.Shape)
Example #22
0
    def execute(self, obj):
        def error(msg):
            func_name = "{} (Sketch_On_Surface)  : ".format(obj.Label)
            FreeCAD.Console.PrintError(func_name + msg + "\n")

        if not obj.Sketch:
            error("No Sketch attached")
            return
        skedges = []
        for i in obj.Sketch.Geometry:
            if i.Construction and obj.ConstructionBounds:
                skedges.append(i.toShape())
            elif not i.Construction and not obj.ConstructionBounds:
                skedges.append(i.toShape())
            #else:
            #debug("toShape() error, ignoring geometry")
        comp = Part.Compound(skedges)

        bb = comp.BoundBox
        u0, u1, v0, v1 = (bb.XMin, bb.XMax, bb.YMin, bb.YMax)
        debug("Sketch bounds = {}".format((u0, u1, v0, v1)))

        try:
            n = eval(obj.Sketch.Support[0][1][0].lstrip('Face'))
            face = obj.Sketch.Support[0][0].Shape.Faces[n - 1]
            #face.Placement = obj.Sketch.Support[0][0].getGlobalPlacement()
        except (IndexError, AttributeError, SyntaxError) as e:
            error("Failed to get the face support of the sketch\n")
            return
        debug("Target face bounds = {}".format(face.ParameterRange))

        if obj.ReverseU:
            u0, u1 = u1, u0
        if obj.ReverseV:
            v0, v1 = v1, v0
        pts = [[FreeCAD.Vector(u0, v0, 0),
                FreeCAD.Vector(u0, v1, 0)],
               [FreeCAD.Vector(u1, v0, 0),
                FreeCAD.Vector(u1, v1, 0)]]
        bs = stretched_plane(pts, face.ParameterRange, 10.0)
        quad = bs.toShape()
        quad.Placement = obj.Sketch.getGlobalPlacement()
        imput_shapes = [obj.Sketch.Shape] + [o.Shape for o in obj.ExtraObjects]
        shapes_1 = []
        shapes_2 = []
        if (obj.Offset == 0):
            shapes_1 = self.map_shapelist(imput_shapes, quad, face,
                                          obj.FillFaces)
        else:
            f1 = face.makeOffsetShape(obj.Offset, 1e-3)
            shapes_1 = self.map_shapelist(imput_shapes, quad, f1.Face1,
                                          obj.FillFaces)
        if (obj.Thickness == 0):
            if shapes_1:
                obj.Shape = Part.Compound(shapes_1)
            return
        else:
            f2 = face.makeOffsetShape(obj.Offset + obj.Thickness, 1e-3)
            shapes_2 = self.map_shapelist(imput_shapes, quad, f2.Face1,
                                          obj.FillFaces)
            if not obj.FillExtrusion:
                if shapes_1 or shapes_2:
                    obj.Shape = Part.Compound(shapes_1 + shapes_2)
                    return
            else:
                shapes = []
                for i in range(len(shapes_1)):
                    if isinstance(shapes_1[i], Part.Face):
                        faces = shapes_1[i].Faces + shapes_2[i].Faces
                        #error_wires = []
                        for j in range(len(shapes_1[i].Edges)):
                            if obj.FillFaces and shapes_1[i].Edges[j].isSeam(
                                    shapes_1[i]):
                                continue
                            ruled = Part.makeRuledSurface(
                                shapes_1[i].Edges[j], shapes_2[i].Edges[j])
                            faces.append(ruled)
                            #try:
                            #face_is_closed = False
                            #for ed in shapes_1[i].Wires[j].Edges:
                            #if ed.isSeam(shapes_1[i]):
                            #face_is_closed = True
                            #debug("closed face detected")
                            #loft = Part.makeLoft([shapes_1[i].Wires[j], shapes_2[i].Wires[j]], False, True, face_is_closed, 5)
                            #faces.extend(loft.Faces)
                            #except Part.OCCError:
                            ##error_wires.extend([shapes_1[i].Wires[j], shapes_2[i].Wires[j]])
                            #FreeCAD.Console.PrintError("Sketch on surface : failed to create loft face ({},{})".format(i,j))
                        try:
                            shell = Part.Shell(faces)
                            shell.sewShape()
                            solid = Part.Solid(shell)
                            shapes.append(solid)
                        except Part.OCCError:
                            FreeCAD.Console.PrintWarning(
                                "Sketch on surface : failed to create solid #{}.\n"
                                .format(i + 1))
                            shapes.extend(faces)
                    else:
                        ruled = Part.makeRuledSurface(shapes_1[i].Wires[0],
                                                      shapes_2[i].Wires[0])
                        shapes.append(ruled)
                #shapes.append(quad)
                if shapes:
                    if len(shapes) == 1:
                        obj.Shape = shapes[0]
                    elif len(shapes) > 1:
                        obj.Shape = Part.Compound(shapes)
Example #23
0
def aa():    
    #-------------------- kann weg/reuse otherwhere
    if 1:
        pass
    else:
        
        ss=Part.sortEdges(col)
        poles=[]
        polesseg=[]
        for w in ss[0]:
            wn=w.toNurbs()
            pls=wn.Edge1.Curve.getPoles()
            if len(polesseg)>0:
                if (pls[0]- polesseg[-1][-1]).Length<0.001:
                    pass
                else:
                    pls.reverse()
            polesseg += [pls]
            poles += pls
        
        degA=self.getData("degree")   
        ls=int(len(polesseg)/2)
        poles=[]
        k=self.getData("tangentForce")
        
        pfak=degA
        pfak=0 # fuer weiche uebergaenge
        
        for i in range(ls):
            ll= (polesseg[2*i][0]-polesseg[2*i][1]).Length
            k *= 0.1*ll
            poles += [ polesseg[2*i][0]]*pfak
            try:
                poles += [
                    polesseg[2*i][0] + (polesseg[2*i][0]- polesseg[2*i-1][-2]).normalize()*k,
                    polesseg[2*i][1] + (polesseg[2*i][1] -polesseg[2*i+1][1]).normalize()*k,
                    ]
            except:
                say("no tangantes possible")
                poles += [
                    polesseg[2*i][0] + (polesseg[2*i][0]- polesseg[2*i-1][-2]),
                    polesseg[2*i][1] + (polesseg[2*i][1] -polesseg[2*i+1][1]),
                    ]

                pass
            poles += [polesseg[2*i][1]]*pfak
            
            poles +=polesseg[2*i+1]
        
        sh=Part.makePolygon(poles)
        sf=Part.BSplineCurve()

        poles=np.array(poles)
        (countA,_)=poles.shape

        multA=[degA+1]+[1]*(countA-1-degA)+[degA+1]
        knotA=range(len(multA))

        sf=Part.BSplineCurve()
        n=self.getData("rotateAxis")
        poles2=np.concatenate([poles[n:],poles[:n]]);poles=poles2
        
        sf.buildFromPolesMultsKnots(poles,multA,knotA,False,degA)

        sh=sf.toShape()

        if 0 and self.getData("createFace"):
            t=len(multA)//3-1
            sf1=sf.copy()
            sf2=sf.copy()
            sf3=sf.copy()
            sf2.segment(0,t)
            sf3.segment(t,2*t)
            sf1.segment(2*t,len(multA)-1)

            sh=Part.Compound([sf2.toShape(),sf3.toShape(),sf1.toShape()])
            Part.show(sh)
            tt=FreeCAD.ActiveDocument.ActiveObject
            surf=FreeCAD.ActiveDocument.addObject("Surface::GeomFillSurface","Surface")
            surf.BoundaryList=[(tt, ('Edge1', 'Edge2', 'Edge3'))]

            FreeCAD.ActiveDocument.recompute(None,True,True)


        if  self.getData("createFace"):
            t=len(multA)//2
            sf1=sf.copy()
            sf2=sf.copy()
            sf2.segment(0,t)          
            sf1.segment(t,len(multA)-1)
            sh=Part.Compound([sf2.toShape(),sf1.toShape()])
            e2=sf1.toShape().Edge1
            e2.reverse()
            sh=Part.makeRuledSurface(sf2.toShape().Edge1,e2)
      

         
            
    self.setPinObject("Shape_out",sh)
Example #24
0
   def execute(self, obj):
        l = obj.Height
        rf = obj.HeightRandom
        f = obj.Face[0].getSubObject(obj.Face[1][0])
        face = Part.Face (f)
        (umin, umax, vmin, vmax) = face.ParameterRange
        # print (umin,umax,vmin,vmax)
    
        nbU = obj.U
        nbV = obj.V
        nbptsU = nbU + 1
        nbptsV = nbV + 1
        
        comp = 0
        lattice = [[0] * nbptsV for j in range(nbptsU)] #tableau coordonnées des points
        shapes = [] 
  
        i = j = 0
        for u in [umin + x * (umax-umin)/nbU for x in range(nbptsU)]:
            for v in [vmin + x * (vmax-vmin)/nbV for x in range(nbptsV)]:
                lattice[i][j] = face.valueAt(u,v)
                j += 1
            j = 0       
            i += 1    
            
        if obj.Style == "Points" :
            if l: 
                for i in range (nbptsU):
                    for j in range(nbptsV):
                        pts2 = lattice[i][j]+face.normalAt(*face.Surface.parameter(lattice[i][j]))*(l+rf*random.random())
                        shapes.append (Part.makeLine(lattice[i][j],pts2))
            else:
                for i in range (nbptsU):
                    for j in range(nbptsV):
                        shapes.append(Part.Vertex(lattice[i][j]))
   
        if obj.Style == "Squares" or obj.Style == "Squares Streched":
            for i in range (nbU):
                for j in range(nbV):
                    p1 = lattice[i][j]
                    p2 = lattice[i][j+1]
                    p3 = lattice[i+1][j]
                    p4 = lattice[i+1][j+1]
                    w1 = Part.makeLine (p1,p2)
                    w2 = Part.makeLine (p3,p4)
                    lf = Part.makeRuledSurface (w1,w2)          # carreau de base
                    
                    if obj.Style == "Squares" and l:
                        g = lf.CenterOfMass
                        v = -lf.normalAt(*lf.Surface.parameter(g))*(l+rf*random.random())
                        ps = g + v                              # point sommet
                        if obj.Sharp:
                            line1 = Part.makeLine (p1,ps)
                            line2 = Part.makeLine (p2,ps)
                            rs1 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p2,ps)
                            line2 = Part.makeLine (p4,ps)
                            rs2 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p4,ps)
                            line2 = Part.makeLine (p3,ps)
                            rs3 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p3,ps)
                            line2 = Part.makeLine (p1,ps)
                            rs4 = Part.makeRuledSurface (line1,line2)
                            shell = Part.Shell(lf.Faces+rs1.Faces+rs2.Faces+rs3.Faces+rs4.Faces)
                            shell.sewShape()
                            solid = Part.Solid(shell)
                            shapes.append(solid)
                        else:                        
                            shapes.append(lf.extrude(v))
  
                        
                    if obj.Style == "Squares Streched" and l:    
                        haz = rf*random.random()
                        q1 = p1+face.normalAt(*face.Surface.parameter(p1))*(l+haz)
                        q2 = p2+face.normalAt(*face.Surface.parameter(p2))*(l+haz)
                        q3 = p3+face.normalAt(*face.Surface.parameter(p3))*(l+haz)
                        q4 = p4+face.normalAt(*face.Surface.parameter(p4))*(l+haz)
                        poly1 = Part.makePolygon ([p1,p2,p4,p3,p1])
                        poly2 = Part.makePolygon ([q1,q2,q4,q3,q1])
                        tour = Part.makeLoft ([poly1,poly2])
                        line1 = Part.makeLine (q1,q2)
                        line2 = Part.makeLine (q3,q4)
                        line3 = Part.makeLine (p1,p2)
                        line4 = Part.makeLine (p3,p4)
                        rs1 = Part.makeRuledSurface (line1,line2)
                        rs2 = Part.makeRuledSurface (line3,line4)
                        shell = Part.Shell(tour.Faces+rs1.Faces+rs2.Faces)
                        shell.sewShape()
                        solid = Part.Solid(shell)
                        shapes.append(solid)
                    else: shapes.append(lf)
                
        if obj.Style == "Diamonds":
            if nbU%2 == 0 and nbV%2 == 0: # check if U and V are even:
                for i in range(0,nbU,2):
                    for j in range(0,nbV,2):
                        p1 = lattice[i+1][j]
                        p2 = lattice[i][j+1]
                        p3 = lattice[i+2][j+1]
                        p4 = lattice[i+1][j+2]
                        w1 = Part.makeLine (p1,p2)
                        w2 = Part.makeLine (p3,p4)
                        lf = Part.makeRuledSurface (w1,w2)
                        
                        if l and obj.Sharp:
                            pc = lattice[i+1][j+1]
                            v = pc+lf.normalAt(*lf.Surface.parameter(pc))*(-l+rf*random.random())
                            line1 = Part.makeLine (p1,p2)
                            line2 = Part.makeLine (p1,v)
                            rs1 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p2,p4)
                            line2 = Part.makeLine (p2,v)
                            rs2 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p1,p3)
                            line2 = Part.makeLine (p1,v)
                            rs3 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p3,p4)
                            line2 = Part.makeLine (v,p4)
                            rs4 = Part.makeRuledSurface (line1,line2)
                           
                            shell = Part.Shell(lf.Faces+rs1.Faces+rs2.Faces+rs3.Faces+rs4.Faces)
                            shell.sewShape()
                            solid = Part.Solid(shell)
                            shapes.append(solid)
                            
                        if l and not obj.Sharp:  
                            p1 = lattice[i+1][j]
                            p2 = lattice[i][j+1]
                            p3 = lattice[i+1][j+2]
                            p4 = lattice[i+2][j+1]
                            
                            L1 = Part.makeLine (p1,p2)
                            L2 = Part.makeLine (p2,p3)
                            L3 = Part.makeLine (p3,p4)
                            L4 = Part.makeLine (p4,p1)
                            diams1 = Part.Wire([L1,L2,L3,L4])
                            
                            p1_2 = p1+face.normalAt(*face.Surface.parameter(p1))*(l+rf*random.random())
                            p2_2 = p2+face.normalAt(*face.Surface.parameter(p2))*(l+rf*random.random())
                            p3_2 = p3+face.normalAt(*face.Surface.parameter(p3))*(l+rf*random.random())
                            p4_2 = p4+face.normalAt(*face.Surface.parameter(p4))*(l+rf*random.random())
                            L1 = Part.makeLine (p1_2,p2_2)
                            L2 = Part.makeLine (p2_2,p3_2)
                            L3 = Part.makeLine (p3_2,p4_2)
                            L4 = Part.makeLine (p4_2,p1_2)
                            diams2 = Part.Wire([L1,L2,L3,L4])
                            cotes = Part.makeLoft([diams1,diams2])
                            L3 = Part.makeLine (p4_2,p3_2)
                            haut = Part.makeRuledSurface (L1,L3)
       
                            if obj.Solid:
                                shell = Part.Shell(haut.Faces+cotes.Faces+lf.Faces)
                                shell.sewShape()
                                diams = Part.Solid(shell)
                               
                            else : diams = Part.makeLoft([diams1,diams2],False,True)
                            shapes.append(diams)
                            
                            
                        else: shapes.append(lf)
            else:
                print ("U and V must a multiple of 2")
                
        if obj.Style == "Small Squares":
            if nbU%2 == 0 and nbV%2 == 0:
               for i in range(0,nbU,2):
                    for j in range(0,nbV,2): 
                        p1 = lattice[i+1][j+1]
                        p2 = lattice[i+1][j+2]
                        p3 = lattice[i+2][j+2]
                        p4 = lattice[i+2][j+1]
         
                        w1 = Part.makeLine (p1,p2)
                        w2 = Part.makeLine (p4,p3)
                        lf = Part.makeRuledSurface (w1,w2)
                        g = lf.CenterOfMass
                        v = -lf.normalAt(*lf.Surface.parameter(g))*(l+rf*random.random())
                        ps = g+v
                        
                        if l!=0 and obj.Sharp:
                            line1 = Part.makeLine (p1,p2)
                            line2 = Part.makeLine (p1,ps)
                            rs1 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p2,p3)
                            line2 = Part.makeLine (p2,ps)
                            rs2 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p1,p4)
                            line2 = Part.makeLine (p1,ps)
                            rs3 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p3,p4)
                            line2 = Part.makeLine (ps,p4)
                            rs4 = Part.makeRuledSurface (line1,line2)
                           
                            shell = Part.Shell(lf.Faces+rs1.Faces+rs2.Faces+rs3.Faces+rs4.Faces)
                            shell.sewShape()
                            solid = Part.Solid(shell)
                            shapes.append(solid)
                        
                        if l and not obj.Sharp:  shapes.append(lf.extrude(v))   
                        else: shapes.append(lf)
            else:
                print ("U and V must be a multiple of 2")    
                
        if obj.Style == "PedestriansWalk":
            if nbU%3 == 0 and nbV%6 == 0:
               for i in range(0,nbU,3):
                    for j in range(0,nbV,6): 
                        p1 = lattice[i+1][j+1]
                        p2 = lattice[i+1][j+5]
                        p3 = lattice[i+2][j+5]
                        p4 = lattice[i+2][j+1]
         
                        w1 = Part.makeLine (p1,p2)
                        w2 = Part.makeLine (p4,p3)
                        lf = Part.makeRuledSurface (w1,w2)
                        
                        g = lf.CenterOfMass
                        v = -lf.normalAt(*lf.Surface.parameter(g))*(l+rf*random.random())
                        ps = g+v
                        
                        if l and obj.Sharp:
                            line1 = Part.makeLine (p1,p2)
                            line2 = Part.makeLine (p1,ps)
                            rs1 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p2,p3)
                            line2 = Part.makeLine (p2,ps)
                            rs2 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p1,p4)
                            line2 = Part.makeLine (p1,ps)
                            rs3 = Part.makeRuledSurface (line1,line2)
                            line1 = Part.makeLine (p3,p4)
                            line2 = Part.makeLine (ps,p4)
                            rs4 = Part.makeRuledSurface (line1,line2)
                           
                            shell = Part.Shell(lf.Faces+rs1.Faces+rs2.Faces+rs3.Faces+rs4.Faces)
                            shell.sewShape()
                            solid = Part.Solid(shell)
                            shapes.append(solid)
                        
                        if l and not obj.Sharp:   shapes.append(lf.extrude(v))   
                        else: shapes.append(lf)
            else:
                print ("U and V must be a multiple of 6")            

        if obj.Style == "Checkers":
            if nbU%2 == 0 and nbV%2 == 0:
               for i in range(0,nbU,1):
                    d = 0
                    if i%2 !=0 : d = 1
                    for j in range(0,nbV-d,2): 
                        
                        p1 = lattice[i][j+d]
                        p2 = lattice[i+1][j+d]
                        p3 = lattice[i][j+1+d]
                        p4 = lattice[i+1][j+1+d]
         
                        w1 = Part.makeLine (p1,p2)
                        w2 = Part.makeLine (p3,p4)
                        lf = Part.makeRuledSurface (w1,w2)                  #carreau de base
                        
                        if l:
                            g = lf.CenterOfMass
                            v = lf.normalAt(*lf.Surface.parameter(g))*(l+rf*random.random())
                            ps = g + v                                     # point sommet
                            
                            if obj.Sharp:
                                line1 = Part.makeLine (p1,ps)
                                line2 = Part.makeLine (p2,ps)
                                rs1 = Part.makeRuledSurface (line1,line2)
                                line1 = Part.makeLine (p2,ps)
                                line2 = Part.makeLine (p4,ps)
                                rs2 = Part.makeRuledSurface (line1,line2)
                                line1 = Part.makeLine (p4,ps)
                                line2 = Part.makeLine (p3,ps)
                                rs3 = Part.makeRuledSurface (line1,line2)
                                line1 = Part.makeLine (p3,ps)
                                line2 = Part.makeLine (p1,ps)
                                rs4 = Part.makeRuledSurface (line1,line2)
                                shell = Part.Shell(lf.Faces+rs1.Faces+rs2.Faces+rs3.Faces+rs4.Faces)
                                shell.sewShape()
                                solid = Part.Solid(shell)
                                shapes.append(solid)
                            else:
                                shapes.append(lf.extrude(v))
                        else: shapes.append(lf)
            else:
                print ("U and V must be a multiple of 2")            
                
        if obj.Style == "Hatch":
            
           for i in range(0,nbU):
                for j in range(0,nbV): 
                    p1 = lattice[i][j]
                    p2 = lattice[i+1][j+1]
                        
                    L1 = Part.makeLine(p1, p2)
                    seg1 = Part.Wire([L1])
                    rand = rf*random.random()
                    if l:
                        p1_2 = p1+f.normalAt(*f.Surface.parameter(p1))*(l+rand)
                        p2_2 = p2+f.normalAt(*f.Surface.parameter(p2))*(l+rand)
                        L2 = Part.makeLine(p1_2, p2_2)
                        seg2 = Part.Wire([L2])
                        loft = Part.makeLoft([seg1,seg2])
                            
                        shapes.append(loft)
                    else :  shapes.append(seg1)
  
        if obj.Style == "Bubble":
            if nbU%2 == 0 and nbV%2 == 0: # check if U and V are even:
                nbU=nbV=2
                for i in range (0,nbU,2):
                    for j in range(0,nbV,2):
                        pts=[]
                        # pts.append(lattice[i][j+1])
                        # pts.append(lattice[i+1][j+2])
                        # pts.append(lattice[i+2][j+1])
                        # pts.append(lattice[i+1][j])
                        pts.append(lattice[i+1][j])
                        pts.append(lattice[i+2][j+1])
                        pts.append(lattice[i+1][j+2])
                        pts.append(lattice[i][j+1])
                        
                        curve=Part.BSplineCurve()
                        # curve.increaseDegree(4)
                        curve.interpolate(pts,True)
                        # curve.setPeriodic()
                        # pc = lattice[i+1][j+1]
                        # norm = face.normalAt(*face.Surface.parameter(pc))
                        print(pts)
 
                        shapes.append(curve)
            else:
                print ("U and V must a multiple of 2")        
         
        if obj.Style == "Honeycomb":
            if nbU%3 == 0 and nbV%3 == 0:
               for i in range(0,nbU,3):
                    for j in range(0,nbV,3): 
                        p1 = lattice[i+1][j]
                        p2 = lattice[i][j+1]
                        p3 = lattice[i][j+2]
                        p4 = lattice[i+1][j+3]
                        p5 = lattice[i+2][j+3]
                        p6 = lattice[i+3][j+2]
                        p7 = lattice[i+3][j+1]
                        p8 = lattice[i+2][j]
                        L1 = Part.makeLine(p1, p2)
                        L2 = Part.makeLine(p2, p3)
                        L3 = Part.makeLine(p3, p4)
                        L4 = Part.makeLine(p4, p5)
                        L5 = Part.makeLine(p5, p6)
                        L6 = Part.makeLine(p6, p7)
                        L7 = Part.makeLine(p7, p8)
                        L8 = Part.makeLine(p8, p1)
                       
                        hexa = Part.Wire([L1,L2,L3,L4,L5,L6,L7,L8])
     
                        rand = rf*random.random()
                        if l:
                            p1_2 = p1+f.normalAt(*f.Surface.parameter(p1))*(l+rand)
                            p2_2 = p2+f.normalAt(*f.Surface.parameter(p2))*(l+rand)
                            p3_2 = p3+f.normalAt(*f.Surface.parameter(p3))*(l+rand)
                            p4_2 = p4+f.normalAt(*f.Surface.parameter(p4))*(l+rand)
                            p5_2 = p5+f.normalAt(*f.Surface.parameter(p5))*(l+rand)
                            p6_2 = p6+f.normalAt(*f.Surface.parameter(p6))*(l+rand)
                            p7_2 = p7+f.normalAt(*f.Surface.parameter(p7))*(l+rand)
                            p8_2 = p8+f.normalAt(*f.Surface.parameter(p8))*(l+rand)
                            
                            L1 = Part.makeLine(p1_2, p2_2)
                            L2 = Part.makeLine(p2_2, p3_2)
                            L3 = Part.makeLine(p3_2, p4_2)
                            L4 = Part.makeLine(p4_2, p5_2)
                            L5 = Part.makeLine(p5_2, p6_2)
                            L6 = Part.makeLine(p6_2, p7_2)
                            L7 = Part.makeLine(p7_2, p8_2)
                            L8 = Part.makeLine(p8_2, p1_2)
                       
                            hexa2 = Part.Wire([L1,L2,L3,L4,L5,L6,L7,L8])
                            loft = Part.makeLoft([hexa,hexa2])
                            
                            shapes.append(loft)
                        else :  shapes.append(hexa)
            else:
                print ("U and V must be a multiple of 3")      
  
  
  
        if shapes: comp=Part.Compound(shapes) 
        if comp: 
            if obj.Limit:
                if l!=0:
                    # c = face.valueAt((umax+umin)/2,(vmax+vmin)/2)
                    c = face.CenterOfMass
                    Vup = c+face.normalAt(*face.Surface.parameter(c))*(l*1.1)
                    Vdn = c+face.normalAt(*face.Surface.parameter(c))*(-l*1.1)
                    ShapeFace1 = face.extrude(Vup-c)
                    ShapeFace = ShapeFace1.fuse(face.extrude(Vdn-c))
                    obj.Shape = comp.common(ShapeFace,0.1)
                else:
                    obj.Shape = comp.common(face,0.1)
               
            else:   obj.Shape = comp