Example #1
0
def shape_from_ref(r):
    with parameter(immediate_mode, False):
        obj = _geometry_from_id(r)
        ref = native_ref(r)
        if isinstance(obj, geo.Point):
            return point.new_ref(ref, fromPt(obj.Location))
        elif isinstance(obj, geo.Curve):
            if rh.IsLine(r) or rh.IsPolyline(r):
                if rh.IsCurveClosed(r):
                    return polygon.new_ref(
                        ref, [fromPt(p) for p in rh.CurvePoints(r)[:-1]])
                else:
                    return line.new_ref(ref,
                                        [fromPt(p) for p in rh.CurvePoints(r)])
            elif obj.IsCircle(Rhino.RhinoMath.ZeroTolerance):
                return circle.new_ref(ref, fromPt(rh.CircleCenterPoint(r)),
                                      rh.CircleRadius(r))
            elif rh.IsCurveClosed(r):
                return closed_spline.new_ref(
                    ref, [fromPt(p) for p in rh.CurvePoints(r)])
            else:
                return spline.new_ref(ref,
                                      [fromPt(p) for p in rh.CurvePoints(r)])
        elif rh.IsObject(r) and rh.IsObjectSolid(r):
            return solid(native_ref(r))
        elif rh.IsSurface(r) or rh.IsPolysurface(r):
            return surface(native_ref(r))
        else:
            raise RuntimeError("{0}: Unknown Rhino object {1}".format(
                'shape_from_ref', r))
Example #2
0
def get_two_curves():

    # get list of selected objects
    sel = rs.SelectedObjects()

    # clear selection
    rs.UnselectAllObjects()

    # if there were 2 objects selected...
    if len(sel) == 2:
        c1, c2 = sel
        # ...and they are curves...
        if rs.IsCurve(c1) and rs.IsCurve(c2):
            # the closed one is the cross-section, the open one is profile
            if rs.IsCurveClosed(c2):
                return c1, c2
            elif rs.IsCurveClosed(c1):
                return c2, c1

    # none of the things above worked, ask the user
    profile = rs.GetObject('Pick the profile curve', rs.filter.curve)

    # let user cancel
    if profile is None:
        return None, None

    cross = rs.GetObject('Pick the cross-section curve', rs.filter.curve)

    # return the curves
    return profile, cross
Example #3
0
def surface_discrete_mapping(srf_guid, discretisation, minimum_discretisation = 5, crv_guids = [], pt_guids = []):
	"""Map the boundaries of a Rhino NURBS surface to planar poylines dicretised within some discretisation using the surface UV parameterisation.
	Curve and point feautres on the surface can be included.
	Parameters
	----------
	srf_guid : guid
		A surface guid.
	crv_guids : list
		List of guids of curves on the surface.
	pt_guids : list
		List of guids of points on the surface.
	discretisation : float
		The discretisation of the surface boundaries.
	minimum_discretisation : int
		The minimum discretisation of the surface boundaries.
	Returns
	-------
	tuple
		Tuple of the mapped objects: outer boundary, inner boundaries, polyline_features, point_features.
	"""

	srf = RhinoSurface.from_guid(srf_guid)

	# a boundary may be made of multiple boundary components and therefore checking for closeness and joining are necessary
	mapped_borders = []

	for i in [1, 2]:
		mapped_border = []

		for border_guid in srf.borders(type = i):
			points = [list(srf.point_xyz_to_uv(pt)) + [0.0] for pt in rs.DivideCurve(border_guid, max(int(rs.CurveLength(border_guid) / discretisation) + 1, minimum_discretisation))]
			
			if rs.IsCurveClosed(border_guid):
				points.append(points[0])
			
			mapped_border.append(points)
			rs.DeleteObject(border_guid)
		mapped_borders.append(mapped_border)

	outer_boundaries, inner_boundaries = [network_polylines(Network.from_lines([(u, v) for border in mapped_borders[i] for u, v in pairwise(border)])) for i in [0, 1]]
	
	# mapping of the curve features on the surface
	mapped_curves = []

	for crv_guid in crv_guids:

		curve = RhinoCurve.from_guid(crv_guid)
		points = [list(srf.point_xyz_to_uv(pt)) + [0.0] for pt in curve.divide(max(int(curve.length() / discretisation) + 1, minimum_discretisation))]
		
		if curve.is_closed():
			points.append(points[0])
		
		mapped_curves.append(points)

	polyline_features = network_polylines(Network.from_lines([(u, v) for curve in mapped_curves for u, v in pairwise(curve)]))

	# mapping of the point features onthe surface
	point_features = [list(srf.point_xyz_to_uv(rs.PointCoordinates(pt_guid))) + [0.0] for pt_guid in pt_guids]

	return outer_boundaries[0], inner_boundaries, polyline_features, point_features
Example #4
0
 def get_curve(self):
     crv = rs.GetObject("Select Closed Curve", rs.filter.curve)
     if rs.IsCurveClosed(crv) is True:
         self.curve = crv
         #self.get_name()
     else:
         print "This curve is not closed"
Example #5
0
def export_curdatapoints():
    object_id = rs.GetObject("Select curve", rs.filter.curve)
    if( object_id==None ): return

    #Get the filename to create
    filter = "Text File (*.shf)|*.shf|All Files (*.*)|*.*||"
    filename = rs.SaveFileName("Save point coordinates as", filter)
    if( filename==None ): return
    if rs.IsCurveClosed(object_id):
        start_point = rs.GetPoint("Base point of center line")
    
        end_point = rs.GetPoint("Endpoint of center line", start_point)
        
        points = rs.CurveContourPoints(object_id, start_point, end_point)
    else:
        points = rs.CurveContourPoints(object_id,rs.CurveStartPoint(object_id),rs.CurveEndPoint(object_id))
    if not points: return
    

    file = open( filename, "w" )
    for pt in points:
        print(str(pt.X)+","+str(pt.Y)+","+str(pt.Z))
        file.write( str(pt.X) )
        file.write( ", " )
        file.write( str(pt.Y) )
        file.write( ", " )
        file.write( str(pt.Z) )
        file.write( "\n" )
    file.close()
def main(bEcho=True, bDebug=False):

    objrefs = getInput()
    if not objrefs: return

    rc = convertObjrefsToSortedBrepsAndEdges(objrefs)
    if rc is None: return

    gBreps, idxs_Edges_per_Brep = rc

    sc.doc.Objects.UnselectAll()

    gCurves_Borders_PerBrep = processBrepObjects(gBreps, idxs_Edges_per_Brep,
                                                 bEcho, bDebug)
    if gCurves_Borders_PerBrep is None: return

    sc.doc.Views.Redraw()

    gCurve_ct = 0
    iOpenCurve_ct = 0
    for gCurves_borders in gCurves_Borders_PerBrep:
        for gCurve in gCurves_borders:
            if not rs.IsCurveClosed(gCurve): iOpenCurve_ct += iOpenCurve_ct
            gCurve_ct += 1

    if not iOpenCurve_ct:
        print "{} curve(s) added to document, and all are closed.".format(
            gCurve_ct)
    else:
        print "{} curve(s) added to document, and {} are open.".format(
            gCurve_ct, iOpenCurve_ct)
Example #7
0
def pre_process():
    # delete all previous user text
    all_objs = rs.AllObjects()
    for obj in all_objs:
        rh_obj = rs.coercerhinoobject(obj)
        rh_obj.Attributes.DeleteAllUserStrings()

    # remove all blocks
    for block in rs.BlockNames():
        rs.DeleteBlock(block)

    # set current layer
    rs.CurrentLayer(relevant_layers_dict["buildings"])

    # remove redundant layers
    for layer_name in rs.LayerNames():
        if layer_name not in relevant_layers_dict.values():
            rs.PurgeLayer(layer_name)

    # get all objects in building layer
    building_objs = rs.ObjectsByLayer(relevant_layers_dict["buildings"])

    for building_obj in building_objs:
        if rs.IsCurve(building_obj) and rs.IsCurveClosed(building_obj):

            # flatten curve to XY plane
            matrix = rs.XformPlanarProjection(rg.Plane.WorldXY)
            rs.TransformObject(building_obj, matrix, copy=False)

            # delete all object with a surface grater or smaller from MIN_BUILDING_AREA_SQ by TOLERANCE or just smaller than MIN_BUILDING_AREA_SQ
            TOLERANCE = 2
            if rs.CurveArea(building_obj)[0] < MIN_BUILDING_AREA_SQM or abs(
                    rs.CurveArea(building_obj)[0] -
                    MIN_BUILDING_AREA_SQM) < TOLERANCE:
                rs.DeleteObject(building_obj)
Example #8
0
def FindMostDistantPointInCurve(obj, resolution = 20):
    """
    Returns the approximately most distant point within a closed curve
    inputs:
        obj (curve): closed planar curves
        resolution (int)[optional]: numbers of sample points in a resolutionXresolution grid
    returns:
        point (point): point furthest from curve
    """
    if rs.IsCurve(obj) == False:
        print "Curves supported only"
        return None
    if rs.IsCurvePlanar(obj) == False:
        print "Curve not planar"
        return None
    if rs.IsCurveClosed(obj) == False:
        print "Curve not closed"
        return None


    rhobj = rs.coercecurve(obj)
    bbox = rhobj.GetBoundingBox(rs.WorldXYPlane())

    minX = bbox.Min[0]
    minY = bbox.Min[1]
    minZ = bbox.Min[2]

    maxX = bbox.Max[0]
    maxY = bbox.Max[1]
    maxZ = bbox.Max[2]

    xVals = []
    yVals = []

    for i in range(resolution):
        xVals.append(i)
        yVals.append(i)

    newXvals = RemapList(xVals, minX, maxX)
    newYvals = RemapList(yVals, minY, maxY)

    furthestPt = None
    furthestDist = 0
    maxDist = 99999
    for xVal in newXvals:
        for yVal in newYvals:
            newPt = rc.Geometry.Point3d(xVal, yVal, minZ)
            result =  rhobj.Contains(newPt, rs.WorldXYPlane())
            if result == rc.Geometry.PointContainment.Inside:
                param = rhobj.ClosestPoint(newPt, maxDist)
                crvPt = rhobj.PointAt(param[1])
                dist = rs.Distance(crvPt, newPt)
                if dist > furthestDist:
                    furthestPt = newPt
                    furthestDist = dist
    if furthestDist == 0:
        return None
    return furthestPt
Example #9
0
def del_noattr_plt():
    # get all objects in plots layer
    plot_objs = rs.ObjectsByLayer(relevant_layers_dict["plots"])

    for plot_obj in plot_objs:
        if rs.IsCurve(plot_obj) and rs.IsCurveClosed(plot_obj):
            some_attrib = rs.GetUserText(plot_obj, plot_attribs_list[0])
            if some_attrib == None:
                rs.DeleteObject(plot_obj)
Example #10
0
def ColorBySize():
    try:
        objs = rs.GetObjects("Select objects to color",
                             1073815613,
                             preselect=True)
        if objs is None: return
        print "Select First Color"
        firstColor = rs.GetColor()
        if firstColor is None: return
        print "Select Second Color"
        secondColor = rs.GetColor(firstColor)
        if secondColor is None: return

        rs.EnableRedraw(False)

        colorLine = rs.AddLine(firstColor, secondColor)

        areas = []
        for obj in objs:
            if rs.IsCurve(obj):
                if rs.IsCurveClosed(obj):
                    areas.append(rs.CurveArea(obj)[0])
                else:
                    areas.append(rs.CurveLength(obj))
            elif rs.IsSurface(obj):
                areas.append(rs.SurfaceArea(obj)[0])
            elif rs.IsPolysurface(obj):
                if rs.IsPolysurfaceClosed(obj):
                    areas.append(rs.SurfaceVolume(obj)[0])
            elif rs.IsHatch(obj):
                areas.append(rs.Area(obj))
            else:
                print "Only curves, hatches, and surfaces supported"
                return

        newAreas = list(areas)
        objAreas = zip(newAreas, objs)
        objAreas.sort()
        objSorted = [objs for newAreas, objs in objAreas]

        areas.sort()
        normalParams = utils.RemapList(areas, 0, 1)

        colors = []
        for t in normalParams:
            param = rs.CurveParameter(colorLine, t)
            colors.append(rs.EvaluateCurve(colorLine, param))

        for i, obj in enumerate(objSorted):
            rs.ObjectColor(obj, (colors[i].X, colors[i].Y, colors[i].Z))

        rs.DeleteObject(colorLine)
        rs.EnableRedraw(True)
        return True
    except:
        return False
Example #11
0
    def process(self):

        if rs.IsPoint(self.nurbs_curve):
            self.preview = self.get_cut_path_point(self.cut_curve)
        elif self.compensation == 0 and not rs.IsCurveClosed(self.nurbs_curve):
            self.preview = self.get_cut_path_open(self.cut_curve)
        else:
            self.preview = self.get_cut_path_closed(self.cut_curve)

        self.gcode = self.get_g_code(self.preview)
def ReturnObjectOutline(objects):
    listOfObjOutlines = []
    for id in objects:
        for t in id:
            # check if closed curve
            if rs.IsCurveClosed(t):
                if rs.Area(t) > 1000:
                    listOfObjOutlines.append(t)
                    break
    return listOfObjOutlines
Example #13
0
def DivideCurveByLengths(curve, lengths):
    # 根据各分段点到起点的长度,含起始点,确定分段点
    points = []
    # print lengths
    for leng in lengths:
        p = CurveLengthPoint(curve, leng)
        points.append(p)
    if rs.IsCurveClosed(curve):
        points = points[:-1]
    return points
Example #14
0
def DimAngles(obj, offset):
    curve = rs.coercecurve(obj)
    segments = curve.DuplicateSegments()
    for i, segment in enumerate(segments):
        if i == len(segments) - 1:
            break
        DimSegmentAngle(segments[i], segments[i + 1], offset)
        print ""
    if rs.IsCurveClosed(obj):
        DimSegmentAngle(segments[-1], segments[0], offset)
Example #15
0
def get_polyline_points(polylines):
    polys = {}
    for key, id in enumerate(polylines):
        polys[key] = {}
        if not rs.IsCurveClosed(id):
            print str(id) + " is an open curve"
            rs.MessageBox(str(id) + " is an open curve")
            return None
        polys[key]['points'] = rs.PolylineVertices(id)[:-1]
        polys[key]['id'] = id
    return polys
Example #16
0
File: test.py Project: tmshv/sisu
def test_is_curve_closed(options):
    layer_name = options['layer']
    geom = get_geometry_by_layer(layer_name)
    if len(geom) == 0:
        return None

    for x in geom:
        valid = rs.IsCurveClosed(x)
        if not valid:
            return False
    return True
Example #17
0
 def test_get_boundary_polyline(self):
     #deprivated, since now in general not drwaing lines
     #However, if needed can easily specifically draw cut lines
     island.make_five_by_five_square_island(self.island)
     self.island.clear()
     self.island.draw_edges()
     boundary = self.island.get_boundary_polyline()
     self.assertTrue(rs.IsPolyCurve(boundary))
     self.assertTrue(rs.IsCurveClosed(boundary))
     self.assertTrue(rs.IsCurvePlanar(boundary))
     self.island.clear()
Example #18
0
    def is_closed(self):
        """Assess if the curve is closed.

        Returns
        -------
        bool
            True if the curve is closed. False otherwise.

        """

        return rs.IsCurveClosed(self.guid)
Example #19
0
 def get_boundary_polyline(self):
     '''
     NOTE: draw_edges must be called before running this function!
     find the polyline composed of all cut edges, which by definition form the 
     boundary of this island
     '''
     assert self.cut_edge_lines, "cut_edge_linesis empty, make sure have drawn island first"
     new_curves = rs.JoinCurves(self.cut_edge_lines, delete_input=False)
     assert len(new_curves) == 1, "more than one curve created!"
     curve = new_curves[0]
     assert rs.IsCurveClosed(curve), "curve {} is not closed".format(curve)
     return curve
Example #20
0
def offsetBothCrvs(crvs, width):
    if rs.IsCurveClosed(crvs):
        domain = rs.CurveDomain(crvs)
        parameter = (domain[0] + domain[1]) / 2.0
        rs.CurveSeam(crvs, parameter)
    offsets = []
    offsets.append(rs.OffsetCurve(crvs, [0, 0, 0], width / 2))
    offsets.append(rs.OffsetCurve(crvs, [0, 0, 0], -width / 2))
    section = rs.AddLoftSrf(offsets, loft_type=2)

    if offsets: rs.DeleteObjects(offsets)
    return section
def iterativeshortencurve():
    curve_id = rs.GetObject("Open curve to smooth", 4, True)
    if curve_id is None or rs.IsCurveClosed(curve_id): return

    min = rs.Distance(rs.CurveStartPoint(curve_id), rs.CurveEndPoint(curve_id))
    max = rs.CurveLength(curve_id)
    goal = rs.GetReal("Goal length", 0.5 * (min + max), min, max)
    if goal is None: return

    while rs.CurveLength(curve_id) > goal:
        rs.EnableRedraw(False)
        curve_id = smoothcurve(curve_id, 0.1)
        rs.EnableRedraw(True)
        if curve_id is None: break
Example #22
0
def curveErrorCheck(curve):

    if rs.IsCurveClosed(curve):
        error = False
    else:
        print "Failed...Curve must be closed"
        error = True

    if rs.IsCurvePlanar(curve):
        error = error
    else:
        print "Failed...Curve must be planar"
        error = True
    return error
Example #23
0
def wallBaseSrf(crv, width):
    rs.SimplifyCurve(crv)
    if rs.IsCurveClosed(crv):
        domain = rs.CurveDomain(crv)
        parameter = (domain[0] + domain[1]) / 2.0
        rs.CurveSeam(crv, parameter)
    offsets = map(lambda x: rs.OffsetCurve(crv, [0, 0, 0], x),
                  [width / 2, -width / 2])
    section = rs.AddLoftSrf(offsets, loft_type=2)

    if offsets: rs.DeleteObjects(offsets)
    if rs.IsPolysurface(section):
        return rs.ExplodePolysurfaces(section, delete_input=True)
    return section
Example #24
0
    def OffsetCurve(self, level_cut):

        check_presision = 10
        offset_type = 1
        branched_curves = []
        main_curve = level_cut
        offset_distance = self.general_input["cut_diam"] * self.input_data[
            "xy_dist"]
        curve_1 = rs.OffsetCurve(main_curve,
                                 rs.CurveAreaCentroid(main_curve)[0], -.1,
                                 None, offset_type)
        curve_2 = rs.OffsetCurve(main_curve,
                                 rs.CurveAreaCentroid(main_curve)[0], .1, None,
                                 offset_type)

        if curve_1 and curve_2:
            if len(curve_1) != 1 or len(curve_2) != 1:
                rs.DeleteObjects(curve_1)
                rs.DeleteObjects(curve_2)
                return branched_curves

        mini_test = self.getSmall(curve_1, curve_2)
        do_points = rs.DivideCurve(mini_test, check_presision, False)
        rs.DeleteObjects([curve_1, curve_2])
        do_points.append(rs.CurveAreaCentroid(main_curve)[0])

        for i in range(0, len(do_points)):
            new_offset_curve = rs.OffsetCurve(main_curve, do_points[i],
                                              offset_distance, None,
                                              offset_type)
            try:
                if self.isCurveNew(branched_curves,
                                   new_offset_curve) and rs.IsCurveClosed(
                                       new_offset_curve) and self.isSmall(
                                           new_offset_curve, main_curve):
                    branched_curves.append(new_offset_curve)
                else:
                    rs.DeleteObject(new_offset_curve)
            except:
                if new_offset_curve:
                    rs.DeleteObjects(new_offset_curve)

        for curve in branched_curves:
            rs.ObjectColor(curve, color_palette["cut"])

        if not branched_curves or len(branched_curves) > 1:

            branched_curves.append("sec_plane")

        return branched_curves
Example #25
0
def checkCurveIntegrity(objs):

    layers = []
    selection = []
    delete_objs = []

    for i, obj in enumerate(objs):
        if rs.IsCurve(obj):
            layer_name = rs.ObjectLayer(obj)
            # check for disconnected endpoints
            if (re.search('contour', layer_name, re.IGNORECASE)
                    or re.search('Pocket', layer_name,
                                 re.IGNORECASE)) and not rs.IsCurveClosed(obj):
                selection.append(obj)
                appendLayer(layers, obj)

                delete_objs.append(rs.AddPoint(rs.CurveStartPoint(obj)))
                delete_objs.append(rs.AddPoint(rs.CurveEndPoint(obj)))

                rs.Command("'_printDisplay _state _on _Enter")

                for i in range(0, 3):
                    temp_circle = rs.AddCircle(rs.WorldXYPlane(), 80.0 * i + 1)
                    rs.MoveObject(temp_circle, rs.CurveStartPoint(obj))
                    rs.ObjectPrintWidth(temp_circle, 2.0)
                    delete_objs.append(temp_circle)

    if len(selection) > 0:
        rs.SelectObjects(selection)
        rs.ZoomSelected()
        redraw()

    # when an object is found on > 0 layers, prompt for proceed
    if len(layers) > 0:

        msg = "See selection: curves and contours should always be closed:\n"
        for layer in layers:
            msg = msg + "- " + layer + " \n"

        msg = msg + '\n Do you want to proceed?'

        rs.DeleteObjects(delete_objs)

        if rs.MessageBox(msg, 1) != 1:
            # do not proceed with export
            return False

    # else

    return True
Example #26
0
def del_noattr_bld():
    # get all objects in plots layer
    building_objs = rs.ObjectsByLayer(relevant_layers_dict["buildings"])

    attribute_labels_list = []
    with open(proc_attributes_path, "r") as input_handle:
        rdr = csv.reader(input_handle)
        attribute_labels_list = next(rdr)

    for building_obj in building_objs:
        if rs.IsCurve(building_obj) and rs.IsCurveClosed(building_obj):
            some_attrib = rs.GetUserText(building_obj,
                                         attribute_labels_list[0])
            if some_attrib == None:
                rs.DeleteObject(building_obj)
Example #27
0
 def __init__(self, curve, input_data, general_input, compensation,
              pocketing):
     self.log = []
     self.input_data = input_data
     self.general_input = general_input
     self.compensation = compensation
     self.pocketing = pocketing
     self.asignedcluster = -1
     self.iscluster = False
     self.nurbs_curve = curve
     self.curve = curve  #Curva original2
     self.type = "point" if rs.IsPoint(
         self.nurbs_curve) else "curve" if rs.IsCurveClosed(
             self.nurbs_curve) else "open_curve"
     self.point = self.curve if rs.IsPoint(
         self.nurbs_curve) else rs.CurveAreaCentroid(
             self.nurbs_curve)[0] if rs.IsCurveClosed(
                 self.nurbs_curve) else rs.CurveStartPoint(
                     self.nurbs_curve)  # Centroide curva original
     self.start_point = rs.PointCoordinates(
         self.nurbs_curve, False) if rs.IsPoint(
             self.nurbs_curve) else rs.CurveStartPoint(self.nurbs_curve)
     self.cut_curve = self.get_cut_curve()
     self.time = 10
Example #28
0
def extr_bld_flr():
    # Extrude all buildings according to NUM_FLOORS attribute multiplied by FLOOR_HEIGHT constant
    # get all objects in building layer
    building_objs = rs.ObjectsByLayer(relevant_layers_dict["buildings"])
    for building_obj in building_objs:
        if rs.IsCurve(building_obj) and rs.IsCurveClosed(
                building_obj
        ) and rs.CurveArea(building_obj)[0] > MIN_BUILDING_AREA_SQM:
            crv = rs.coercecurve(building_obj)
            num_of_floors = rs.GetUserText(building_obj, "NUM_FLOORS")
            building_height = FLOOR_HEIGHT_M * int(num_of_floors)
            srf = rs.ExtrudeCurveStraight(crv, (0, 0, 0),
                                          (0, 0, building_height))
            rs.CapPlanarHoles(srf)

    rs.ViewDisplayMode(rs.CurrentView(), "Shaded")
Example #29
0
def surface_border_kinks(surface_guid):
    kinks = []
    borders = surface_borders(surface_guid)
    for curve_guid in borders:
        start_tgt = rs.CurveTangent(curve_guid,
                                    rs.CurveParameter(curve_guid, 0))
        end_tgt = rs.CurveTangent(curve_guid, rs.CurveParameter(curve_guid, 1))
        if not rs.IsCurveClosed(curve_guid) or not rs.IsVectorParallelTo(
                start_tgt, end_tgt):
            start = rs.CurveStartPoint(curve_guid)
            end = rs.CurveEndPoint(curve_guid)
            if start not in kinks:
                kinks.append(start)
            if end not in kinks:
                kinks.append(end)
    return kinks
Example #30
0
def AddTEtoOpenAirfoil(AirfoilCurve):
    # If the airfoil curve given as an argument is open at the trailing edge, it adds
    # a line between the ends of the curve and joins this with the rest of the curve.
    if rs.IsCurveClosed(AirfoilCurve) == False:
        EP1 = rs.CurveEndPoint(AirfoilCurve)
        rs.ReverseCurve(AirfoilCurve)
        EP2 = rs.CurveEndPoint(AirfoilCurve)
        rs.ReverseCurve(AirfoilCurve)
        Closure = rs.AddLine(EP1, EP2)
        rs.UnselectAllObjects()
        rs.SelectObject(Closure)
        rs.SelectObject(AirfoilCurve)
        rs.Command("_Join ")
        LO = rs.LastCreatedObjects()
        AirfoilCurve = LO[0]
        rs.UnselectAllObjects()

    return AirfoilCurve