def ProjectOnSrfLoose(): crv = rs.GetObject("select curve to loosely project", rs.filter.curve) srf = rs.GetObject("Select surface to loosely project onto", rs.filter.surface) if crv == None or srf == None: return degree = rs.CurveDegree(crv) bPeriodic = False pts = rs.CurvePoints(crv) if rs.IsCurvePeriodic(crv): pts = rs.CullDuplicatePoints(pts, 0.01) bPeriodic = True pts_projected = [] curveplane = rs.CurvePlane(crv) projection_dir = curveplane.ZAxis for pt in pts: pp = rs.ProjectPointToSurface(pt, srf, projection_dir) if len(pp) > 0: pt_projected = pp[0] pts_projected.append(pt_projected) if len(pts_projected) <= 2: return if len(pts_projected) < len(pts): bPeriodic = False nc = Rhino.Geometry.NurbsCurve.Create(bPeriodic, degree, pts_projected) sc.doc.Objects.AddCurve(nc) sc.doc.Views.Redraw()
def Func(crvID): if rs.IsLine(crvID): plane = rs.ViewCPlane() else: plane = rs.CurvePlane(crvID) crv = sc.doc.Objects.Find(crvID).Geometry # if t_style==1: trans=Rhino.Geometry.CurveOffsetCornerStyle.Sharp # elif t_style==2: trans=Rhino.Geometry.CurveOffsetCornerStyle.Round # elif t_style==3: trans=Rhino.Geometry.CurveOffsetCornerStyle.Smooth # elif t_style==4: trans=Rhino.Geometry.CurveOffsetCornerStyle.Chamfer offset1 = crv.Offset(plane, dist, tol, trans) offset1ID = sc.doc.Objects.AddCurve(offset1[0])
def OffsetCurve2Sides(crvID, dist, t_style, conn, tol): if rs.IsLine(crvID): plane = rs.ViewCPlane() else: plane = rs.CurvePlane(crvID) crv = sc.doc.Objects.Find(crvID).Geometry if t_style == 1: trans = Rhino.Geometry.CurveOffsetCornerStyle.Sharp elif t_style == 2: trans = Rhino.Geometry.CurveOffsetCornerStyle.Round elif t_style == 3: trans = Rhino.Geometry.CurveOffsetCornerStyle.Smooth elif t_style == 4: trans = Rhino.Geometry.CurveOffsetCornerStyle.Chamfer offset1 = crv.Offset(plane, dist, tol, trans) if offset1: offset2 = crv.Offset(plane, -dist, tol, trans) if offset2: if len(offset1) == 1 and len(offset2) == 1: offset1ID = sc.doc.Objects.AddCurve(offset1[0]) offset2ID = sc.doc.Objects.AddCurve(offset2[0]) if conn >= 0 and not rs.IsCurveClosed(crvID): AddEndsToOffset(offset1ID, offset2ID, conn, dist) #don't care if ends get made or not, exit afterward return True
def contour (crvOffset): # get geometry surfaceId = rs.GetObject("pick surface to contour", 0, True, True) startPt = rs.GetPoint("base point of contours") endPt = rs.GetPoint("end point of contours") count = 0 reference = [] target = [] # make contours & store in newCrvs newCrvs = rs.AddSrfContourCrvs(surfaceId, (startPt, endPt), crvOffset) # output is a list of GUIDs. can't access raw points # divide the target surface printBed = rs.GetObject("pick surface for layout", 8, True, True) intCount = len(newCrvs) uDomain = rs.SurfaceDomain(printBed, 0) vDomain = rs.SurfaceDomain(printBed, 1) uStep = (uDomain[1] - uDomain[0]) / intCount for u in rs.frange(uDomain[0], uDomain[1], uStep): layout = rs.SurfaceFrame(printBed, [u,1]) target1 = layout[0] # set target to point inside of object - note this is a single point target2 = rs.PointAdd(target1,(0,10,0)) # this could be more parametric target.extend([target1, target2]) #print target # add text, reference and orient! # for orient, we need a list 3 points to reference and 3 points to target! # maybe reference should be curve origin crvPl[0] and midpoint? or else polyline verticies -- need to convert curve to polyline first? for crv in newCrvs: count += 1 # for label crvPl = rs.CurvePlane(crv) # plane for text rs.AddText(count, crvPl, 0.25) # should you label on the ground? #crvPl = rs.PointAdd(crvPl[0], (0,0,-1)) # if you wanted to offset text ref1 = rs.CurveMidPoint(crv) ref2 = crvPl[0] reference.extend([ref1, ref2])
def dimensionPline(pline, offsetDist): try: if rs.IsCurvePlanar(pline): pass else: print "Curve must be planar" return segments = [] dimGroup = rs.AddGroup("Pline Dims") dir = rs.ClosedCurveOrientation(pline) if dir == -1: rs.ReverseCurve(pline) normal = rs.CurvePlane(pline).ZAxis segments = rs.ExplodeCurves(pline) if len(segments)<1: segments = [rs.CopyObject(pline)] for seg in segments: if rs.IsLine(seg): endPt = rs.CurveEndPoint(seg) stPt = rs.CurveStartPoint(seg) tanVec = rs.VectorCreate(stPt, endPt) offsetVec = rs.VectorRotate(tanVec, 90, normal) offsetVec = rs.VectorUnitize(offsetVec) offsetVec = rs.VectorScale(offsetVec, offsetDist) offsetPt = rs.VectorAdd(stPt, offsetVec) dim = rs.AddAlignedDimension(stPt, endPt, rs.coerce3dpoint(offsetPt), 'PCPA_12') rs.AddObjectToGroup(dim, dimGroup) rs.DeleteObjects(segments) result = True except: result = False return [dimGroup, result]
def Crv2ViewLoose(): curve1 = rs.GetObject("select first curve", rs.filter.curve) if curve1 != None: rs.LockObject(curve1) curve2 = rs.GetObject("select second curve", rs.filter.curve) if curve1 == None or curve2 == None: return degree1 = rs.CurveDegree(curve1) degree2 = rs.CurveDegree(curve2) pts1 = rs.CurvePoints(curve1) pts2 = rs.CurvePoints(curve2) error = False errors = [] if rs.IsPolyCurve(curve1) or rs.IsPolyCurve(curve2): errors.append("Error: This script only works for single open curves") error = True if not rs.IsCurvePlanar(curve1) or not rs.IsCurvePlanar(curve2): errors.append("Error: One or more of the input curves is not planar.") error = True if rs.IsCurvePeriodic(curve1) or rs.IsCurvePeriodic(curve2): errors.append("Error: This script only works with open curves") error = True if len(pts1) != len(pts2): errors.append( "Error: Input curves need to have same amount of control points") error = True if rs.CurveDegree(curve1) != rs.CurveDegree(curve2): errors.append("Error: Input curves need to be of same degree") error = True if error: for err in errors: print err rs.UnlockObject(curve1) return top = 0 right = 0 front = 0 if rs.CurvePlane(curve1).ZAxis[2] != 0: #top view curve top = 1 if rs.CurvePlane(curve2).ZAxis[2] != 0: #top view curve top = 2 if rs.CurvePlane(curve1).ZAxis[0] != 0: #right view curve right = 1 if rs.CurvePlane(curve2).ZAxis[0] != 0: #right view curve right = 2 if rs.CurvePlane(curve1).ZAxis[1] != 0: #front view curve front = 1 if rs.CurvePlane(curve2).ZAxis[1] != 0: #front view curve front = 2 pts3 = [] #array to store the points for the new curve if top == 1 and right == 2: for i in range(0, len(pts1)): pts1[i][2] = pts2[i][2] pts1[i][1] = (pts1[i][1] + pts2[i][1] ) / 2 #average out y-coordinate of each point pts3.append(pts1[i]) if top == 2 and right == 1: for i in range(0, len(pts1)): pts2[i][2] = pts1[i][2] pts2[i][1] = (pts1[i][1] + pts2[i][1] ) / 2 #average out y-coordinate of each point pts3.append(pts2[i]) if top == 1 and front == 2: for i in range(0, len(pts1)): pts1[i][2] = pts2[i][2] pts1[i][0] = (pts1[i][0] + pts2[i][0] ) / 2 #average out x-coordinate of each point pts3.append(pts1[i]) if top == 2 and front == 1: for i in range(0, len(pts1)): pts2[i][2] = pts1[i][2] pts2[i][0] = (pts1[i][0] + pts2[i][0] ) / 2 #average out x-coordinate of each point pts3.append(pts2[i]) rs.UnlockObject(curve1) if (right == 0 and front == 0) or (top == 0 and right == 0) or (top == 0 and front == 0): print "Error: Curves need to be placed on orthogonal views" return else: rs.AddCurve(pts3, degree1)
def prepareToolpaths(toolpathName, objects, mode, totalDepth, passDepth, toolDiameter): objectNr = 1 pathSegmentNr = 1 lastPoint = [] for id in objects: plane = rs.CurvePlane(id) # place point inside or outside the object (it is needed for the offset) if mode == "Inside": point = rs.CurveAreaCentroid(id)[0] else: point = rs.XformCPlaneToWorld([10000, 10000, 0], plane) tempCurve = rs.OffsetCurve(id, point, toolDiameter / 2.0, plane.ZAxis) if not tempCurve: print "Tool cannot do this toolpath" return False passPoint = rs.CurveStartPoint(tempCurve) if objectNr > 1: objId = rs.AddLine(lastPoint, [passPoint.X, passPoint.Y, safetyHeight]) setSegmentId(objId, pathSegmentNr) pathSegmentNr = pathSegmentNr + 1 setFeedrate(objId, feedrateMove) objId = rs.AddLine([passPoint.X, passPoint.Y, safetyHeight], [passPoint.X, passPoint.Y, 0]) setSegmentId(objId, pathSegmentNr) pathSegmentNr = pathSegmentNr + 1 setFeedrate(objId, feedratePlunge) if objectNr == 1: labelId = rs.AddTextDot(toolpathName, [passPoint.X, passPoint.Y, safetyHeight]) rs.SetUserText(labelId, "LayerId", rs.LayerId("Toolpaths::" + pathLayerName)) lastPass = False passNr = 1 prevDepth = 0 while True: depth = passNr * passDepth # if the depth is lower, set it to max and mark for last pass if depth >= totalDepth: depth = totalDepth lastPass = True objId = rs.AddLine([passPoint.X, passPoint.Y, -prevDepth], [passPoint.X, passPoint.Y, -depth]) setSegmentId(objId, pathSegmentNr) setFeedrate(objId, feedratePlunge) pathSegmentNr = pathSegmentNr + 1 prevDepth = depth # add the toolpath and move it to current depth toolpathCurve = rs.CopyObject(tempCurve) rs.MoveObject(toolpathCurve, [0, 0, -depth]) setSegmentId(toolpathCurve, pathSegmentNr) setFeedrate(toolpathCurve, feedrateCutting) passNr = passNr + 1 pathSegmentNr = pathSegmentNr + 1 if lastPass == True: break # add the exit move lastPoint = [passPoint.X, passPoint.Y, safetyHeight] objId = rs.AddLine([passPoint.X, passPoint.Y, -depth], lastPoint) setSegmentId(objId, pathSegmentNr) setFeedrate(objId, feedrateRetract) pathSegmentNr = pathSegmentNr + 1 # remove the helper curve rs.DeleteObject(tempCurve) objectNr = objectNr + 1 return True
def OffsetCrvLoose(): crv = rs.GetObject("select curve to offset loosely", rs.filter.curve, True) if crv == None: return if not rs.IsCurvePlanar(crv): print "Sorry, but that curve is not planar." return if rs.IsPolyCurve(crv): print "This simple script works only for single open or closed curves" return offset = rs.GetReal("offset amount", 5) if offset == None or offset == 0: return both_sides = rs.GetBoolean("Offset both sides?", ["both_sides", "off", "on"], False)[0] bPeriodic = False #rs.EnableRedraw(False) pts = rs.CurvePoints(crv) degree = rs.CurveDegree(crv) if rs.IsCurvePeriodic(crv): pts = rs.CullDuplicatePoints(pts, 0.01) bPeriodic = True offset_pts = [] offset_pts2 = [] #if both_sides=true plane = rs.CurvePlane(crv) axis = plane.ZAxis for pt in pts: cp = rs.CurveClosestPoint(crv, pt) v = rs.CurveTangent(crv, cp) v = rs.VectorUnitize(v) v *= offset v = rs.VectorRotate(v, 90, axis) pt_ = rs.AddPoint(pt) #create points for offset on one side of the curve movedpt = rs.MoveObject(pt_, v) newpt = rs.coerce3dpoint(movedpt) offset_pts.append(newpt) #create points for offset on other side of the curve movedpt = rs.MoveObject(pt_, -2 * v) newpt = rs.coerce3dpoint(movedpt) offset_pts2.append(newpt) rs.DeleteObject(pt_) nc = Rhino.Geometry.NurbsCurve.Create(bPeriodic, degree, offset_pts) nc2 = Rhino.Geometry.NurbsCurve.Create(bPeriodic, degree, offset_pts2) if not both_sides: if nc.GetLength(0.1) > nc2.GetLength(0.1): #get the longest curve... if offset > 0: #...and add it to the document for positive offsets... sc.doc.Objects.AddCurve(nc) else: #...or the shortest for negative offsets. sc.doc.Objects.AddCurve(nc2) else: if offset > 0: sc.doc.Objects.AddCurve(nc2) else: sc.doc.Objects.AddCurve(nc) else: #add both curves to the document sc.doc.Objects.AddCurve(nc) sc.doc.Objects.AddCurve(nc2) rs.EnableRedraw(True) sc.doc.Views.Redraw()
# import Rhino.Geometry as rg # import Rhino.Geometry # from Rhino.Geometry import Brep sc.doc = Rhino.RhinoDoc.ActiveDoc # rg.Curve.Offset() print x tol = sc.doc.ModelAbsoluteTolerance dist = -2 crvID = x brepid = y plane = rs.CurvePlane(crvID) #plane = rs.WorldXYPlane() crv = sc.doc.Objects.Find(crvID).Geometry trans = Rhino.Geometry.CurveOffsetCornerStyle.Sharp offset1 = crv.Offset(plane, dist, tol, trans) polysrf = sc.doc.Objects.Find(brepid).Geometry print polysrf curves = polysrf.DuplicateNakedEdgeCurves(1, 1) tolerance = sc.doc.ModelAbsoluteTolerance * 2.1 curves = Rhino.Geometry.Curve.JoinCurves(curves, tolerance) curves = curves[0].Offset(rs.WorldXYPlane(), 2, tol, trans) #curves = curves[0]
def rc_terraincut2(b_obj, building_guids, etching_guids): join_dist = 0 if str(b_obj.ObjectType) != "Brep": b_geo = extrusion_to_brep(b_obj.Geometry) else: b_geo = b_obj.Geometry outline_crv = get_surface_outline(b_geo) #wrh.add_curves_to_layer(outline_crv,1) #extrude down the topography surface in order to take sections bool_merged = Rhino.Geometry.Brep.MergeCoplanarFaces(b_geo, D_TOL) extruded_srf_id = extrude_down_srf(wrh.docobj_to_guid(b_obj)) extruded_srf = rs.coercebrep(extruded_srf_id) #get planes for sectioning. planes = get_section_planes(b_geo, THICKNESS) #get the section curves and the section srfs #rs.Redraw() section_srfs = [] for i, plane in enumerate(planes): #print i #if first level, get brep outline if i > 0: plane_sections = get_section(extruded_srf, plane) else: plane_sections = outline_crv ###DEBUG STARTS#### current_level_srfs = [] for crv in plane_sections: closed = crv.IsClosed if not closed: dist = rs.Distance(crv.PointAtStart, crv.PointAtEnd) res = crv.MakeClosed(dist * 2) join_dist = dist if dist > join_dist else join_dist if res == False: return 0 new_brep = Rhino.Geometry.Brep.CreatePlanarBreps(crv)[0] current_level_srfs.append(new_brep) #new_brep_added = doc.Objects.AddBrep(new_brep) #rs.ObjectLayer(new_brep_added,"s15") ###DEBUG ENDS### section_srfs.append(current_level_srfs) rs.DeleteObject(extruded_srf_id) #get extrusions of section srfs extruded_section_breps = [] boolean_section_breps = [] frame_base_surface = None for i, brep_level in enumerate(section_srfs): extruded_breps = [] for brep in brep_level: srf_added = wrh.add_brep_to_layer(brep, LCUT_IND[2]) if i == 0: frame_base_surface = rs.CopyObject(srf_added) extruded_breps.append(rs.ExtrudeSurface(srf_added, SHORT_GUIDE)) rs.DeleteObject(srf_added) extruded_section_breps.append(extruded_breps) #rs.Redraw() #make voids for existing buildings building_breps = building_guids bldg_subtraction_breps = get_building_booleans(building_breps, planes) if bldg_subtraction_breps: extruded_section_breps = cut_building_volumes(extruded_section_breps, bldg_subtraction_breps) [rs.DeleteObjects(x) for x in bldg_subtraction_breps] #purge the building breps num_divisions = len(section_srfs) frame_brep = get_frame_brep(frame_base_surface, BORDER_THICKNESS, THICKNESS * num_divisions) rs.DeleteObject(frame_base_surface) #boolean out the features final_breps = [] for i, brep_level in enumerate(extruded_section_breps): boolean_level_ind = i + 2 final_level_breps = [] if boolean_level_ind < len(extruded_section_breps): for A_brep in brep_level: final_brep = None B_breps = [] for B_srf in section_srfs[boolean_level_ind]: B_breps.append(rs.ExtrudeSurface(B_srf, LONG_GUIDE)) #truncate the B_breps if BORDER_BOOL: B_breps = [ cut_frame_from_brep(b, frame_brep) for b in B_breps ] #rs.AddLayer("debug6",[50,200,50]) #debug #rs.ObjectLayer(B_breps,"debug6") #handle a bug creating lists of lists sometimes. if isinstance(B_breps[0], (list, )): B_breps = B_breps[0] boolean_result = rs.BooleanDifference([A_brep], B_breps, False) rs.DeleteObjects(B_breps) if boolean_result: final_brep = boolean_result else: final_brep = rs.CopyObjects([A_brep]) rs.DeleteObjects([A_brep]) #rs.ObjectLayer(B_breps,"debug6") #rs.AddLayer("s11",[200,200,50]) #debug #rs.ObjectLayer(final_brep,"s11") #debug final_level_breps.extend(final_brep) else: #rs.ObjectLayer(A_brep,"s11") final_level_breps.extend(brep_level) final_breps.append(final_level_breps) #get the final surfaces by iterating through the final section breps and extracting the top faces. final_srfs = [] for i, breplevel in enumerate(final_breps): final_srfs_level = [] for brep in breplevel: xsrf = wge.get_extreme_srf(rs.coercebrep(brep), 5) final_srfs_level.append( doc.Objects.Add(xsrf[0].DuplicateFace( False))) #must properly type the faces #rs.ObjectLayer(final_srfs_level,"s4") final_srfs.append(final_srfs_level) [rs.DeleteObjects(x) for x in final_breps] #DEBUG #project etching layers to final srfs final_srfs.reverse() #get the boundary curves main_curves = [] guide_curves = [] etch_curves = [] for i, srflevel in enumerate(final_srfs): main_curves_level = [] guide_curves_level = [] etch_curves_level = [] for srf in srflevel: sb = rs.DuplicateSurfaceBorder(srf) sb_outer = rs.DuplicateSurfaceBorder(srf, 1) if sb: main_curves_level.extend(sb) if i < len(final_srfs) - 1 and sb_outer: p = rs.ProjectCurveToSurface(sb_outer, final_srfs[i + 1], [0, 0, -1]) if p: guide_curves_level.extend(p) rs.DeleteObject(sb_outer) if sb_outer: rs.DeleteObject(sb_outer) #refactor... etch_curves_level = project_etching(etching_guids, srflevel) etch_curves.append(etch_curves_level) main_curves.append(main_curves_level) guide_curves.append(guide_curves_level) flat_srf_list = [item for sublist in final_srfs for item in sublist] etch_curves.reverse() main_curves.reverse() guide_curves.reverse() bb = rs.BoundingBox(b_geo) layout_dist = rs.Distance(bb[0], bb[3]) + LASER_GAP preview_dist = rs.Distance(bb[0], bb[1]) + LASER_GAP movement_range = [(i + 1) * layout_dist for i in xrange(len(main_curves))] for i, level_list in enumerate(main_curves): cp_main = rs.CurvePlane(level_list[0]) rs.MoveObjects(level_list, [0, movement_range[i], -cp_main.OriginZ]) if etch_curves[i]: rs.MoveObjects(etch_curves[i], [0, movement_range[i], -cp_main.OriginZ]) if i > 0: cp_guide = rs.CurvePlane(guide_curves[i][0]) rs.MoveObjects(guide_curves[i], [0, movement_range[i - 1], -cp_guide.OriginZ]) main_curves = [item for sublist in main_curves for item in sublist] guide_curves = [item for sublist in guide_curves for item in sublist] etch_curves = [item for sublist in etch_curves for item in sublist] preview_geo = [item for sublist in final_srfs for item in sublist] rs.MoveObjects(preview_geo, [preview_dist, 0, 0]) #close the boundary curves cb_crvs = [] for c in guide_curves: if not rs.IsCurveClosed(c): if rs.IsCurveClosable(c, D_TOL): cb_curves.append(rs.CloseCurve(rs.CopyObject(c))) else: cb_crvs.append(rs.CopyObject(c)) etch_curves = wge.trim_boundary(etch_curves, cb_crvs, D_TOL) rs.DeleteObjects(cb_crvs) rs.DeleteObject(frame_brep) rs.ObjectLayer(main_curves, "XXX_LCUT_01-CUT") rs.ObjectLayer(guide_curves, "XXX_LCUT_03-LSCORE") rs.ObjectLayer(etch_curves, "XXX_LCUT_04-ENGRAVE") rs.ObjectLayer(preview_geo, "XXX_LCUT_00-GUIDES") if join_dist > 0: s = "Had to force-close gaps up to a distance of " + str(join_dist) Rhino.RhinoApp.WriteLine(s) return 1
def create_bone(point, curve, length, width, radius, extend): if not extend: extend = 0.001 curve_surface = rs.AddPlanarSrf(curve) if not curve_surface: exp_curves = rs.ExplodeCurves(curve) curve_surface = rs.AddEdgeSrf(exp_curves) rs.DeleteObjects(exp_curves) print("Surface problem") # circle = rs.AddCircle(rs.CurveAreaCentroid(curve)[0],10000) # planar_surface = rs.AddPlanarSrf(circle) # projected_curve = rs.ProjectCurveToSurface(curve,planar_surface,(0,0,-1)) # if not projected_curve: rs.ProjectCurveToSurface(curve,planar_surface,(0,0,1)) # if not projected_curve: print "noooooo" # curve_surface = rs.AddPlanarSrf(projected_curve) # rs.DeleteObjects([circle,planar_surface,curve]) # curve = rs.JoinCurves(rs.DuplicateEdgeCurves(curve_surface, select=False)) # if not curve_surface: print "WARNING" main_point_param = rs.CurveClosestPoint(curve, point) curve_normal = rs.CurveNormal(curve) curve_plane = rs.CurvePlane(curve) tangent = rs.CurveTangent(curve, main_point_param) center_curve = rs.AddLine((0, 0, 0), rs.VectorScale(tangent, length)) rs.RotateObject(center_curve, (0, 0, 0), 90, curve_normal) rs.MoveObject(center_curve, rs.VectorCreate(point, (0, 0, 0))) if not rs.IsPointOnSurface(curve_surface, rs.CurveEndPoint(center_curve)): rs.RotateObject(center_curve, point, 180, curve_normal) normal = rs.VectorScale(tangent, 10000) normal_inverted = rs.VectorReverse(normal) side_curve = rs.OffsetCurveOnSurface(center_curve, curve_surface, width / 2) if not side_curve: side_curve = rs.OffsetCurveOnSurface(center_curve, curve_surface, -width / 2) side_curves = [ side_curve, rs.RotateObject( side_curve, rs.CurveMidPoint(center_curve), 180, rs.VectorCreate(rs.CurveStartPoint(center_curve), rs.CurveEndPoint(center_curve)), True) ] #side_curves = [side_curve,rs.MirrorObject(side_curve,rs.CurveStartPoint(center_curve),rs.CurveEndPoint(center_curve), True)] #side_curves = [rs.OffsetCurveOnSurface(center_curve,curve_surface, width/2),rs.OffsetCurveOnSurface(center_curve,curve_surface, -width/2)] for side_curve in side_curves: rs.ExtendCurveLength(side_curve, 0, 0, 2) rs.ObjectColor(side_curve, (255, 0, 0)) perimeter_curve = rs.AddCurve([ rs.CurveStartPoint(side_curves[0]), rs.CurveEndPoint(side_curves[0]), rs.CurveEndPoint(side_curves[1]), rs.CurveStartPoint(side_curves[1]), rs.CurveStartPoint(side_curves[0]) ], 1) inside_curve = rs.OffsetCurve(perimeter_curve, rs.CurveAreaCentroid(perimeter_curve)[0], radius * .7) external_curve = rs.OffsetCurve(perimeter_curve, rs.CurveAreaCentroid(perimeter_curve)[0], -extend) e_points = [ rs.CurvePoints(external_curve)[0], rs.CurvePoints(external_curve)[3] ] e_perimeter_curve = rs.AddCurve([ rs.CurveEndPoint(side_curves[1]), rs.CurveEndPoint(side_curves[0]), e_points[0], e_points[1], rs.CurveEndPoint(side_curves[1]) ], 1) center_plane_a = rs.PlaneFromPoints( rs.CurvePoints(inside_curve)[2], rs.CurvePoints(inside_curve)[1], rs.CurvePoints(inside_curve)[3]) center_plane_b = rs.PlaneFromPoints( rs.CurvePoints(inside_curve)[1], rs.CurvePoints(inside_curve)[0], rs.CurvePoints(inside_curve)[2]) circles = [ rs.AddCircle(center_plane_a, radius + RADIUS_TOLERANCE), rs.AddCircle(center_plane_b, radius + RADIUS_TOLERANCE) ] bone_curve = rs.CurveBooleanUnion( [e_perimeter_curve] + circles) if extend else rs.CurveBooleanUnion([perimeter_curve] + circles) rs.DeleteObjects([ inside_curve, center_curve, perimeter_curve, curve_surface, e_perimeter_curve, external_curve ] + side_curves + circles) return bone_curve
def Main(): input_curves = rs.GetObjects("Curves", rs.filter.curve, True, True) input_points = rs.GetObjects("Points for dogboone placement", rs.filter.point) if not input_curves or not input_points: return #Reads, asks and writes settings to document data_name = "dogbone2" values = rs.GetDocumentData(data_name, "settings") values = json.loads(values)["data"] if values else [ "35.0", "15.0", "9.525", "1" ] settings = ["Length:", "With:", "Diameter:", "Tolerance Offset:"] length, width, diam, aperture = [ float(i.replace(" ", "")) for i in rs.PropertyListBox( settings, values, "DogBone by dfmd", "Settings:") ] rs.SetDocumentData(data_name, "settings", json.dumps({"data": [length, width, diam, aperture]})) sorted_points = [] clean_curves = [] rs.EnableRedraw(False) for curve in input_curves: point_list = [] for point in input_points: if rs.PointInPlanarClosedCurve(point, curve, rs.CurvePlane(curve)) == 2: point_list.append(point) if point_list: sorted_points.append(rs.SortPointList(point_list)) #Clean curve # circle = rs.AddCircle(rs.CurveAreaCentroid(curve)[0],10000) # planar_surface = rs.AddPlanarSrf(circle) # projected_curve = rs.ProjectCurveToSurface(curve,planar_surface,(0,0,-1)) # clean_curves.append(projected_curve) # rs.DeleteObjects([circle,planar_surface,curve]) clean_curves.append(curve) #main_curve = rs.GetCurveObject("Selecciona curva",True)[0] #main_points = rs.SortPointList(rs.GetObjects("Selecciona puntos de referencia",rs.filter.point)) #input_curves = rebuild_curves(input_curves) for main_curve in clean_curves: main_points = sorted_points[clean_curves.index(main_curve)] bone_curves = [ create_bone(point, main_curve, length, width, diam / 2, aperture) for point in main_points ] #new_main_curve = rs.CopyObject(rs.ConvertCurveToPolyline(main_curve,False,False,True)) new_main_curve = rs.CopyObject(main_curve) completed = True for bone_curve in bone_curves: buffer_curve = rs.CurveBooleanDifference(new_main_curve, bone_curve) if len(buffer_curve) > 1: rs.DeleteObjects(buffer_curve) rs.DeleteObject(new_main_curve) completed = False break rs.DeleteObject(new_main_curve) new_main_curve = buffer_curve if not completed: super_curve = rs.CurveBooleanUnion(bone_curves) rare_curves = rs.CurveBooleanDifference(main_curve, super_curve) if len(rare_curves) > 1: areas = [rs.CurveArea(i) for i in rare_curves] sorted_curves = [ x for (y, x) in sorted(zip(areas, rare_curves)) ] rs.DeleteObjects(sorted_curves[:-1]) rs.DeleteObject(super_curve) rs.DeleteObjects(bone_curves + [main_curve])