def RunCommand(is_interactive):
    #rs.EnableRedraw(False)
    cplane = rs.ViewCPlane()
    area = 0
    defaultName = ''
    areaObjs = rs.GetObjects("Select Objects", filter=65536, preselect=True)

    if not areaObjs:
        rs.EnableRedraw(True)
        print("No object selected. Exiting command.")
        return

    areaName = rs.GetString(
        "Enter name of area to be displayed", object_names(areaObjs),
        ["RETAIL", "RESIDENTIAL", "AMENITY", "BOH", "LOBBY"])

    if not areaName:
        rs.EnableRedraw(True)
        return

    # GRAPHIC SCALE OPTIONS
    nameOffset = .4
    nameTextSize = 1
    areaTextSize = .8

    scale = rs.GetReal("Text height (in Rhino Units)", defaultScale)
    if not scale:
        print("Text height not entered, exiting command")
        rs.EnableRedraw(True)
        return

    nameOffset = nameOffset * scale
    nameTextSize = nameTextSize * scale
    areaTextSize = areaTextSize * scale

    # GET AREA and Format it to Integer with commas
    area = get_area(areaObjs)
    area = area * (rs.UnitScale(9))**2
    area = int(area)
    area = "{:,} SF".format(area)
    bbox = rs.BoundingBox(areaObjs, cplane)
    pt_sum = bbox[0]
    for i in xrange(1, len(bbox)):
        pt_sum += bbox[i]
    area_avg = rs.AddPoint(pt_sum / len(bbox))

    areaCenter = rs.PointCoordinates(
        rs.MoveObject(area_avg,
                      cplane.YAxis * (nameOffset + areaTextSize) / -2))
    nameCenter = rs.PointCoordinates(
        rs.MoveObject(area_avg, cplane.YAxis * (nameOffset + nameTextSize)))
    #    print(nameCenter, areaCenter)

    # CREATE THE TEXT
    areaText = rs.AddText(area, areaCenter, areaTextSize, justification=2)
    nameText = rs.AddText(areaName, nameCenter, nameTextSize, justification=2)

    # CREATE BOX AROUND TEXT

    textBounds = rs.BoundingBox(areaText, cplane)
    textBoundary = rs.AddPolyline(textBounds[0:5])

    nameTextHeight = rs.Distance(
        rs.BoundingBox(nameText, cplane)[2],
        rs.BoundingBox(nameText, cplane)[1])
    textBorder = rs.OffsetCurve(textBoundary, (0, 0, 0), .25 * scale, style=1)

    rs.DeleteObject(textBoundary)

    rs.ObjectName(nameText, "Name Text")
    rs.ObjectName(areaText, "Area Text")
    rs.ObjectName(textBorder, "Text Border")

    parent = rs.ParentLayer(
        rs.ObjectLayer(areaObjs[0])) + '::' if rs.ParentLayer(
            rs.ObjectLayer(areaObjs[0])) else ''
    # print("LAYER NAME", rs.LayerName(parent+"A-ANNO-NOTE"))

    if not rs.IsLayer(parent + "A-ANNO-NOTE"):
        rs.AddLayer(parent + "A-ANNO-NOTE")
    rs.ObjectLayer(nameText, parent + "A-ANNO-NOTE")
    rs.ObjectLayer(areaText, parent + "A-ANNO-NOTE")
    rs.ObjectLayer(textBorder, parent + "A-ANNO-NOTE")

    areasGroup = rs.AddGroup()
    rs.AddObjectsToGroup([areaText, nameText, textBorder], areasGroup)

    rs.SelectObjects(rs.ObjectsByGroup(areasGroup))
    rs.DeleteObject(area_avg)

    rs.EnableRedraw(True)
Example #2
0
def main():


    # get objects to export
    objs = rs.GetObjects("select objects to Make3d", 0, True, True)
    if not objs: print "make3d aborted"; return
    

        
    defaults = {
        'material_thickness':18
    }
    defaults = getDefaultValues(defaults, 'TNM_make3d')
    
    
    material_thickness = rs.GetReal("Material Thickness", number=defaults['material_thickness'])
    
    storeDefaultValues('TNM_make3d', {'material_thickness':material_thickness} )

    
    
    rs.EnableRedraw(False)

    checkPos(objs)

    set_volumes = []
    set_subtracts = []
    
    
    fail_objects =[]

    for obj in objs:
        if rs.IsBlockInstance(obj):   
            
            # get content
            copy = rs.CopyObject(obj)
            content = ce.explodeBlock( [copy] )
                        
            # filter objects to only curves and points
            copies = ce.filterObjects(content) 
            
            copies = ce.joinCurves(copies)

            # copies = ce.joinCurves(copies)
            ce.simplify(copies)
            
            volumes, subtracts = convertToVolumes(copies, material_thickness)
                        
            parts = volumes
            
            for subtract in subtracts:
                if rs.IsPolysurface(parts[0]) and rs.IsPolysurface(subtract) and rs.IsPolysurfaceClosed(parts[0]) and rs.IsPolysurfaceClosed(subtract):
                    
                    # print parts
                    # print subtract
                    
                    temp_parts =  rs.BooleanDifference(parts, [subtract], False)
                    if temp_parts:
                        print 'subtract success'
                        rs.DeleteObjects(parts)
                        rs.DeleteObject(subtract)
                        
                        parts = temp_parts
                    else:
                        print 'boolean differce failed on: %s' % subtract
                        fail_objects.append(subtract)
                else:
                    print 'boolean differce failed on: %s' % subtract
                    fail_objects.append(subtract)

            
            # addResultToBlock(obj, result)
            
        else:
            # add warning message collision check
            print obj

    rs.UnselectAllObjects()
    rs.SelectObjects(fail_objects)
    
    intersect = None
    # for i, volume in enumerate(set_volumes):
        # for j, subtracts in enumerate(set_subtracts):
            # if(i != j):
                # print rs.ObjectLayer(volume)
                
                # intersect = rs.BooleanIntersection(rs.CopyObject(volume), subtracts, False)
                # if intersect:
                    # rs.SelectObjects(intersect)
                    
                    
            # rs.DeleteObjects(subtracts)

            
       
    
    if intersect:
        rs.MessageBox("ERROR")
        
    rs.DeleteObjects(copies)
    
    ce.redraw()
Example #3
0
    ALLDATA.append(
        [NCOLS, NROWS, XLLCORNER, YLLCORNER, CELLSIZE, NODATA_VALUE])
    ALLDATA.append(cellheights)
    return ALLDATA


DEMdata = readDEM('data/elevTEST.txt')

#assign variables
ncols = DEMdata[0][0]
nrows = DEMdata[0][1]
xllcorner = DEMdata[0][2]
yllcorner = DEMdata[0][3]
cellsize = DEMdata[0][4]
NODATA_value = DEMdata[0][5]

landscape = DEMdata[1]

#draw landscape
rs.EnableRedraw(False)

srfPts = []
for i in range(len(landscape)):
    for j in range(len(landscape[i])):
        nowCellPt = myPos(i, j, landscape)
        srfPts.append(nowCellPt)

srf = rs.AddSrfPtGrid((nrows, ncols), srfPts)

rs.EnableRedraw(True)
Example #4
0
def PopulatePath():
    numObjects = 0
    type = None
    try:
        crvs = rs.GetObjects("Select curves to populate", rs.filter.curve,
                             True)
        if crvs is None: return None
        crvObjs = []
        for crv in crvs:
            crvObjs.append(rs.coercecurve(crv))

        #GET POPULATION TYPE
        type = GetPopulationType()
        if type is None: return None

        #GET BLOCK NAMES
        if type == 'Custom Block':
            blockNames, instances = GetCustomBlockNames()
        else:
            blockNames = GetBlockNames(type)
        if blockNames is None: return

        #GET NUMBER OF OBJECTS
        numObjects = GetNumObjects()
        if numObjects is None: return None

        rs.EnableRedraw(False)
        if type == '2D People' or type == '3D People':
            spacing = 42
        elif type == '2D Trees':
            spacing = 100
        elif type == '3D Trees':
            spacing = 200
        elif type == '3D Vehicles':
            spacing = 240
        else:
            spacing = GetCustomSpacing(
                blockNames[0])  #currently just selects the first block

        #GET PTS
        upVec = rc.Geometry.Vector3d(0, 0, 1)
        plane0 = rc.Geometry.Plane(rc.Geometry.Point3d(0, 0, 0), upVec)
        plane0.Rotate(math.pi / 2, upVec)
        crvData = []
        for i, crvObj in enumerate(crvObjs):
            lengths = []
            frames = []
            curveLength = crvObj.GetLength()
            counter = 0

            while len(frames) < numObjects:
                t = utils.Remap(random.uniform(0, 1), 0, 1, 0, curveLength)

                posOkay = True
                if len(lengths) > 0:
                    counter += 1
                    for eachPrevPos in lengths:
                        if abs(eachPrevPos - t) < spacing:
                            posOkay = False

                if posOkay:
                    lengths.append(t)
                    pt = crvObj.PointAtLength(t)
                    param = crvObj.LengthParameter(t)[1]
                    tan = crvObj.TangentAt(param)
                    xAxis = rc.Geometry.Vector3d.CrossProduct(tan, upVec)
                    xAxis.Reverse()
                    frames.append(rc.Geometry.Plane(pt, tan, xAxis))

                if counter > int(curveLength / numObjects):
                    print "Curve {}: Could only fit {} of the requested {} objects".format(
                        i, len(frames), numObjects)
                    break
            crvData.append(frames)

        scaleVariation = .1
        #PLACE THE BLOCKS
        for i, crvObj in enumerate(crvObjs):
            for i, frame in enumerate(crvData[i]):
                blockName = blockNames[random.randint(0, len(blockNames) - 1)]
                if TryLoadBlock(type, blockName):
                    xform = rc.Geometry.Transform.PlaneToPlane(plane0, frame)
                    eachBlock = rs.InsertBlock2(blockName, xform)
                    try:
                        if type == '2D People' or type == '3D People':
                            layerName = layers.GetLayerNameByNumber(2200)
                        elif type == '2D Trees' or type == '3D Trees':
                            layerName = layers.GetLayerNameByNumber(2300)
                        elif type == '3D Vehicles':
                            layerName = layers.GetLayerNameByNumber(2400)
                        elif type == 'Custom Block':
                            layerName = rs.ObjectLayer(instances[0])
                        else:
                            layers.AddLayerByNumber(2000)
                            layerName = layers.GetLayerNameByNumber(2000)
                        rs.ObjectLayer(eachBlock, layerName)

                        if type != '3D Vehicles':
                            xyScale = random.uniform(1 - scaleVariation,
                                                     1 + scaleVariation)
                            zScale = random.uniform(1 - scaleVariation,
                                                    1 + scaleVariation)
                        else:
                            xyScale = 1
                            zScale = 1
                        rs.ScaleObject(eachBlock, frame,
                                       (xyScale, xyScale, zScale))
                    except:
                        pass
        rs.EnableRedraw(True)
        result = True
    except:
        result = False

    utils.SaveFunctionData('Blocks-Populate Path',
                           [__version__, numObjects, type, result])
import rhinoscriptsyntax as rs
import re
import Rhino
layerDict = {}

rs.EnableRedraw(enable=False)

layerDict["A-ANNO-LEGN"] = {
    "LayerColor": -16711681,
    "LayerPrintColor": -16777216,
    "LayerLinetype": "Continuous",
    "LayerPrintWidth": 0.0
}
layerDict["A-ANNO-NOTE"] = {
    "LayerColor": -16711681,
    "LayerPrintColor": -16777216,
    "LayerLinetype": "Continuous",
    "LayerPrintWidth": 0.0
}
layerDict["A-ANNO-SYMB"] = {
    "LayerColor": -16711681,
    "LayerPrintColor": -16777216,
    "LayerLinetype": "Continuous",
    "LayerPrintWidth": 0.0
}
layerDict["A-AREA"] = {
    "LayerColor": -65536,
    "LayerPrintColor": -16777216,
    "LayerLinetype": "Continuous",
    "LayerPrintWidth": 0.0
}
def main():

    imax = rs.GetInteger('Enter X Value', 40)
    jmax = rs.GetInteger('Enter Y Value', 6)
    zmax = rs.GetInteger('Enter Z Value', 150)

    pointPopulation = []
    point = {}
    rs.EnableRedraw(False)
    for i in range(imax):
        for j in range(jmax):
            x = i
            y = j
            z = 0

            pointID = rs.AddPoint(x, y, z)
            pointPos = rs.PointCoordinates(pointID)
            #pointID = [i,j]
            pointState = rnd.random()
            if pointState > 0.5:
                secondState = 1
            else:
                secondState = 0

            pointState = secondState
            point[(i, j)] = cell(pointID, pointPos, pointState, zmax)
            if pointState <= 0.5:
                rs.DeleteObject(pointID)

    rs.EnableRedraw(True)
    for k in range(zmax):
        rs.EnableRedraw(False)
        for i in range(imax):
            for j in range(jmax):

                if i == 0:
                    iminus1 = imax - 1
                if i > 0:
                    iminus1 = i - 1

                if i == imax - 1:
                    iplus1 = 0
                if i < imax - 1:
                    iplus1 = i + 1

                if j == 0:
                    jminus1 = jmax - 1
                if j > 0:
                    jminus1 = j - 1

                if j == jmax - 1:
                    jplus1 = 0
                if j < jmax - 1:
                    jplus1 = j + 1

                point[(i,
                       j)].live(point[(iminus1, jminus1)], point[(iminus1, j)],
                                point[(iminus1, jplus1)], point[(i, jplus1)],
                                point[(iplus1, jplus1)], point[(iplus1, j)],
                                point[(iplus1, jminus1)], point[(i, jminus1)],
                                k)
        rs.EnableRedraw(True)
Example #7
0
        if ptList[i][j][1]:
            fixMe = True
            BUILDH = int(ptList[i][j][1][1][2] / cellHeight)
            #make sure plant is FALSE

        SAND = int(zCoord / cellHeight)  #no. of sand units on cell

        #introduce something about plant in next line (cell constructor)
        nowCell = gt002.Cell(((i * GRIDY) + j), i, j, nowCellOrigin, GRIDSIZE,
                             GRIDX, GRIDY, SAND, fixMe, cellHeight, windShadow,
                             BUILDH)
        #append our cells to a list
        colList.append(nowCell)
    cellList.append(colList)
"""
rs.EnableRedraw(False)
for i in range(len(cellList)):
    for j in range(len(cellList[i])):
        nowPt = cellList[i][j].cellOrigin
        nowPt[2] = cellList[i][j].sandHeight*cellList[i][j].cellHeight
        pt = rs.AddPoint(nowPt)
        if cellList[i][j].cellFixed==True:
            nowPt[2] = cellList[i][j].buildHeight*cellList[i][j].cellHeight
            rs.ObjectLayer(pt, "buildings")
rs.EnableRedraw(True)
"""

#output data to text file
path = "simulation data/"
fileName = raw_input('File Name?')
Example #8
0
def rhino_volmesh_halfface_pinch(volmesh):
    hfkeys = _select_boundary_halffaces(volmesh)

    key = hfkeys[0]

    center = volmesh.halfface_center(key)
    normal = volmesh.halfface_oriented_normal(key)
    line = (center, add_vectors(center, normal))

    # --------------------------------------------------------------------------
    #  dynamic draw
    # --------------------------------------------------------------------------
    rs.EnableRedraw(True)

    def OnDynamicDraw(sender, e):

        cp = e.CurrentPoint
        plane = (cp, normal)
        line = (center, add_vectors(center, normal))
        it = intersection_line_plane(line, plane)

        translation = subtract_vectors(it, center)
        dot = dot_vectors(normal, translation)
        dot = dot / abs(dot)

        dist = distance_point_point(center, it) * dot

        for hfkey in hfkeys:
            hf_center = volmesh.halfface_center(hfkey)
            hf_normal = volmesh.halfface_oriented_normal(hfkey)
            ep = add_vectors(hf_center, scale_vector(hf_normal, dist))
            e.Display.DrawDottedLine(Point3d(*hf_center), Point3d(*ep),
                                     feedback_color)
            e.Display.DrawPoint(Point3d(*ep), 0, 4, black)
            for vkey in volmesh.halfface_vertices(hfkey):
                sp = volmesh.vertex_coordinates(vkey)
                e.Display.DrawLine(Point3d(*sp), Point3d(*ep), black, 2)

    # --------------------------------------------------------------------------
    #  input point
    # --------------------------------------------------------------------------
    ip = Point3d(*center)
    axis = Rhino.Geometry.Line(ip, ip + Vector3d(*normal))
    gp = get_target_point(axis, OnDynamicDraw)

    plane = (gp, normal)
    it = intersection_line_plane(line, plane)

    translation = subtract_vectors(it, center)
    dot = dot_vectors(normal, translation)
    dot = dot / abs(dot)

    rise = distance_point_point(center, it) * dot

    for hfkey in hfkeys:
        hf_center = volmesh.halfface_center(hfkey)
        hf_normal = volmesh.halfface_oriented_normal(hfkey)
        ep = add_vectors(hf_center, scale_vector(hf_normal, rise))

        volmesh_halfface_pinch(volmesh, hfkey, ep)

    volmesh.draw()

    return volmesh
Example #9
0
 def redraw(self, timeout=None):
     """Redraw the Rhino view."""
     if timeout:
         time.sleep(timeout)
     rs.EnableRedraw(True)
     rs.Redraw()
Example #10
0
idSurface = rs.GetObject("srf to frame? ", 8, True, True)
intCount = rs.GetReal("# of itera. per direction")

#domains are rough dims of the surface - can check via _what
uDomain = rs.SurfaceDomain(idSurface, 0)
vDomain = rs.SurfaceDomain(idSurface, 1)

# get size int from domain & / by intended count = increment between surfaces
uStep = (uDomain[1] - uDomain[0]) / intCount
vStep = (vDomain[1] - vDomain[0]) / intCount

#print uStep
#print vStep

rs.EnableRedraw(False)

# loop through size of surface by step increment in both u & v directions
for u in rs.frange(uDomain[0], uDomain[1], uStep):
    for v in rs.frange(vDomain[0], vDomain[1], vStep):
        pt = rs.EvaluateSurface(idSurface, u,
                                v)  # get points at each domain step
        if rs.Distance(pt, rs.BrepClosestPoint(idSurface, pt)[0]) < 0.1:
            srfFrame = rs.SurfaceFrame(
                idSurface, [u, v])  # create ref plane at each division point
            newPlane = rs.AddPlaneSurface(
                srfFrame, 1.0, 1.0)  # create surface at each ref plane
            # add height guideline from plane's origin to "ceiling"
            centerPt = rs.SurfaceAreaCentroid(
                newPlane)  # locate center of each new plane
            limit = 10  # set "ceiling"
Example #11
0
def ShowStep(step_name):
    rs.EnableRedraw(True)
    input = rs.GetString("Showing step: " + step_name +
                         " (Press Enter to continue)")
    rs.EnableRedraw(False)
Example #12
0
def RunCommand(is_interactive):
    # get input objects
    objs = rs.GetObjects("Select object(s) to connect")
    if (objs is None):
        return 1
    # select source handle
    source = rs.GetObject("Select sender handle (L polyline)", rs.filter.curve)
    if (source is None):
        return 1
    sPoly = rs.coercecurve(source)

    # select destination handle
    receiver = rs.GetObject("Select receiver handle (L polyline)",
                            rs.filter.curve)
    if (receiver is None):
        return 1
    rPoly = rs.coercecurve(receiver)

    if not (rs.IsPolyline(sPoly) & rs.IsPolyline(rPoly)): return 1

    preview = []
    while True:
        # input rotation angle
        rotation = rs.GetReal("Rotation angle (degrees)", 0, -360, 360)
        if rotation is None: break
        rs.EnableRedraw(False)

        # precalculate points, planes and transformation
        sPts = ptsFromPolyline(sPoly)
        rPts = ptsFromPolyline(rPoly)
        sPlane = planeFromPts(sPts)
        rPlane = planeFromPts(rPts)
        origin = rPts[0]
        rPts = rs.RotateObjects(rPts, origin, 180, rPlane.YAxis)
        rPts1 = rs.RotateObjects(rPts, origin, -rotation, rPlane.ZAxis)
        for obj in objs:
            preview.append(rs.OrientObject(obj, sPts, rPts1, 1))

        rs.DeleteObjects(rPts1)
        rs.EnableRedraw(True)
        result = rs.GetString("Looks good?", "Yes", ("Yes", "No"))
        if result is None:
            rs.EnableRedraw(False)
            for obj in preview:
                rs.DeleteObject(obj)
            rs.EnableRedraw(True)
            break
        result = result.upper()
        if result == "YES":
            group_map = []
            for obj in preview:
                obj = rs.coercerhinoobject(obj)
                RhinoUpdateObjectGroups(obj, group_map)
            break
        elif result == "NO":
            rs.EnableRedraw(False)
            for obj in preview:
                rs.DeleteObject(obj)
            rs.EnableRedraw(True)

    # you can optionally return a value from this function
    # to signify command result. Return values that make
    # sense are
    #   0 == success
    #   1 == cancel
    # If this function does not return a value, success is assumed
    return 0
Example #13
0
def drawPts(PTLIST):
    rs.EnableRedraw(False)
    for i in range(len(PTLIST)):
        for j in range(len(PTLIST[i])):
            rs.AddPoint(PTLIST[i][j])
    rs.EnableRedraw(True)
Example #14
0
def PlantGenerator():
    #Ask for a start point of the plant.
    ptRoot = rs.GetPoint("Root point for plant")
    if not ptRoot: return

    #Check all sticky variables for initialization and assign default
    #values if they have not yet been set.
    prop_MinTwigCount = getsticky("MinTwigCount", 0)
    prop_MaxTwigCount = getsticky("MaxTwigCount", 8)
    prop_MaxGenerations = getsticky("MaxGenerations", 5)
    prop_MaxTwigLength = getsticky("MaxTwigLength", 10.0)
    prop_LengthMutation = getsticky("LengthMutation", 0.75)
    prop_MaxTwigAngle = getsticky("MaxTwigAngle", 30.0)
    prop_AngleMutation = getsticky("AngleMutation", 0.85)

    #Collect all growth properties using a series of GetInteger and GetReal methods
    #This could be done a lot cleaner using an iterated Option getter, but that's a lot
    #more code. See chapter 8 on UI methods.

    #Some of these values have limits on their value. See the RhinoScript help
    #for information about the arguments.
    prop_MinTwigCount = rs.GetInteger("Minimum twig count", prop_MinTwigCount)
    if prop_MinTwigCount is None: return

    prop_MaxTwigCount = rs.GetInteger("Maximum twig count", prop_MaxTwigCount,
                                      1)
    if prop_MaxTwigCount is None: return

    prop_MaxGenerations = rs.GetInteger("Maximum branch generations",
                                        prop_MaxGenerations, 1, 1000)
    if prop_MaxGenerations is None: return

    prop_MaxTwigLength = rs.GetReal("Maximum twig length", prop_MaxTwigLength,
                                    0.01)
    if prop_MaxTwigLength is None: return

    prop_LengthMutation = rs.GetReal("Twig length mutation",
                                     prop_LengthMutation, 0.01)
    if prop_LengthMutation is None: return

    prop_MaxTwigAngle = rs.GetReal("Maximum twig angle", prop_MaxTwigAngle,
                                   0.0, 90.0)
    if prop_MaxTwigAngle is None: return

    prop_AngleMutation = rs.GetReal("Twig angle mutation", prop_AngleMutation,
                                    0.01)
    if prop_MaxTwigAngle is None: return

    setsticky("MinTwigCount", prop_MinTwigCount)
    setsticky("MaxTwigCount", prop_MaxTwigCount)
    setsticky("MaxGenerations", prop_MaxGenerations)
    setsticky("MaxTwigLength", prop_MaxTwigLength)
    setsticky("LengthMutation", prop_LengthMutation)
    setsticky("MaxTwigAngle", prop_MaxTwigAngle)
    setsticky("AngleMutation", prop_AngleMutation)

    #Turning of redraw will drastically speed up the tree generation. However, it's quite fun to watch
    #so you might consider switching it off.
    rs.EnableRedraw(False)

    #Collect all tree-growth variables into a single array.
    growthprops = (prop_MinTwigCount, prop_MaxTwigCount, prop_MaxGenerations,
                   prop_MaxTwigLength, prop_LengthMutation, prop_MaxTwigAngle,
                   prop_AngleMutation)

    #Call the recursive function the first time. It will call itself from now on.
    #We also need to tell this first function that is has generation 1
    #We're assuming the growth direction at the root is vertical,
    #so we have to supply a (0,0,1) direction vector.
    RecursiveGrowth(ptRoot, (0, 0, 1), growthprops, 1)

    #After all recursion has completed, be sure to enable the redraw again.
    rs.EnableRedraw(True)
Example #15
0
def redraw():
    rs.EnableRedraw(True)
    rs.Redraw()
Example #16
0
def redraw():
    rs.EnableRedraw(True)
    rs.EnableRedraw(False)
Example #17
0
def densification(mesh, target_length, custom=True):
    """Densifies a quad mesh based on a target length.
	
	Parameters
	----------
	mesh : Mesh
		The quad mesh to densify.
	target_length : float
		Target length for densification.
	custom : bool
		User modification of density parameters.

	Returns
	-------
	dense_mesh: Mesh, None
		Densified quad mesh.
		None if not a quad mesh.

	Raises
	------
	-

	"""

    if not mesh.is_quadmesh():
        return None

    edge_groups, max_group = dual_edge_polylines(mesh)

    dual_polyedges = []
    for i in range(max_group + 1):
        dual_polyedge = []
        for u, v in edge_groups:
            if edge_groups[(u, v)] == i:
                if (v, u) not in dual_polyedge:
                    dual_polyedge.append(([u, v]))
        if len(dual_polyedge) > 0:
            dual_polyedges.append(dual_polyedge)

    # determine subdivision parameter based on target length and dual edge average length
    group_subdivision = {}
    edge_group = {}

    for i, dual_polyedge in enumerate(dual_polyedges):
        average_length = 0
        for u, v in dual_polyedge:
            average_length += mesh.edge_length(u, v)
        average_length /= len(dual_polyedge)

        subdivision_parameter = math.ceil(average_length / target_length)
        group_subdivision[i] = subdivision_parameter

        for u, v in dual_polyedge:
            edge_group[(u, v)] = i
            edge_group[(v, u)] = i

    if custom:
        # propose customization of local density
        count = 100
        while count > 0:
            count -= 1
            rs.EnableRedraw(False)
            all_dots = []
            for dual_polyedge in dual_polyedges:
                u0, v0 = dual_polyedge[0]
                group = edge_group[(u0, v0)]
                parameter = group_subdivision[group]
                dots = []
                for u, v in dual_polyedge:
                    if u > v:
                        continue
                    point = mesh.edge_midpoint(u, v)
                    group = edge_group[(u, v)]
                    parameter = int(group_subdivision[group])
                    dots.append(rs.AddTextDot(parameter, point))
                k = float(group) / float(max_group) * 255
                RGB = [k] * 3
                rs.AddGroup(group)
                rs.ObjectColor(dots, RGB)
                rs.AddObjectsToGroup(dots, group)
                all_dots += dots
            rs.EnableRedraw(True)
            dot = rs.GetObject('edge group to modify', filter=8192)
            if dot is not None:
                group = int(rs.ObjectGroups(dot)[0])
                parameter = rs.GetInteger('subdivision parameter',
                                          number=3,
                                          minimum=1)
                group_subdivision[group] = parameter
            rs.EnableRedraw(False)
            rs.DeleteObjects(all_dots)
            rs.EnableRedraw(True)
            if dot is None:
                break

    # mesh each patch
    meshes = []

    for fkey in mesh.faces():
        a, b, c, d = mesh.face_vertices(fkey)
        # exceptions if pseudo quad face with a (u, u) edge in no groups
        if (a, b) in edge_group:
            group_1 = edge_group[(a, b)]
        else:
            group_1 = edge_group[(c, d)]
        if (b, c) in edge_group:
            group_2 = edge_group[(b, c)]
        else:
            group_2 = edge_group[(d, a)]
        n = int(group_subdivision[group_1])
        m = int(group_subdivision[group_2])
        # subdivision points
        ab = [mesh.edge_point(a, b, float(i) / n) for i in range(0, n + 1)]
        bc = [mesh.edge_point(b, c, float(i) / m) for i in range(0, m + 1)]
        dc = [mesh.edge_point(d, c, float(i) / n) for i in range(0, n + 1)]
        ad = [mesh.edge_point(a, d, float(i) / n) for i in range(0, m + 1)]

        # create mesh
        vertices, face_vertices = discrete_coons_patch(ab, bc, dc, ad)
        face_mesh = PseudoQuadMesh.from_vertices_and_faces(
            vertices, face_vertices)
        meshes.append(face_mesh)

    vertices, face_vertices = join_and_weld_meshes(meshes)
    dense_mesh = PseudoQuadMesh.from_vertices_and_faces(
        vertices, face_vertices)

    # remove pseudo quads: [a, b, c, c] -> [a, b, c]
    for fkey in dense_mesh.faces():
        to_change = False
        face_vertices = dense_mesh.face_vertices(fkey)
        new_face_vertices = []
        for vkey in face_vertices:
            if len(new_face_vertices) == 0 or vkey != new_face_vertices[-1]:
                new_face_vertices.append(vkey)
            else:
                to_change = True
        if new_face_vertices[0] == new_face_vertices[-1]:
            del new_face_vertices[-1]
            to_change = True
        if to_change:
            dense_mesh.delete_face(fkey)
            dense_mesh.add_face(new_face_vertices, fkey)

    # unweld along two-sided openings

    return dense_mesh
Example #18
0
def main():

    # create globally used array of copies
    copies = []
    biesse_layers = []

    # promt convert for biesse

    items = (
        ['convert_to_biesse_layers', 'no', 'yes'],
        ['export_clamex_txt', 'no', 'yes'],
        ['open_after_export', 'no', 'yes'],
    )

    default_values = getDefaultValues()

    options = rs.GetBoolean("conversion options", items, default_values)

    if not options or len(options) < 2:
        print "checkAndExport aborted"
        return

    convert_for_biesse = options[0]
    export_clamex_txt = options[1]
    open_after_export = options[2]

    storeDefaultValues(convert_for_biesse, export_clamex_txt,
                       open_after_export)

    # get objects to export
    objs = rs.GetObjects("select objects to export", 0, True, True)
    if not objs:
        print "checkAndExport aborted"
        return

    rs.EnableRedraw(False)

    # create copies of all block contents
    copies = rs.CopyObjects(objs)

    # explodeblock
    copies = explodeBlock(copies)

    copies = explodeTextObjects(copies)

    # filter objects to only curves and textobjects
    copies = filterObjects(copies)

    # check curves for deviation from c-plane
    if checkCurvePosition(copies):

        clamexdata = None
        if export_clamex_txt:
            clamexdata = extractClamexOrientation(copies)

        # obj properties are lost here
        copies = joinCurves(copies)

        simplify(copies)

        if checkCurveIntegrity(copies):

            # rs.UnselectAllObjects()

            # check curve dir
            if not setCurveDir(copies):
                print "checkAndExport aborted"
                return

            #get left bottom
            rs.EnableRedraw(True)
            selection_origin = rs.GetPoint("Pick export base point")
            rs.EnableRedraw(False)

            # move to origin
            result = moveToOrigin(copies, selection_origin)

            if convert_for_biesse:
                biesse_layers = convertLayers(copies)

            if result:

                # export
                rs.SelectObjects(copies)

                redraw()

                filename = rs.SaveFileName("Save", "dxf Files (*.dxf)|*.dxf||")
                if filename:

                    result = rs.Command('! _-Export "' + filename + '" _Enter',
                                        False)

                    if open_after_export:
                        if os.path.isfile(
                                'C:\Program Files\Rhinoceros 5 (64-bit)\System\Rhino.exe'
                        ):
                            print(
                                '"C:\Program Files\Rhinoceros 5 (64-bit)\System\Rhino.exe" /nosplash /runscript="_-open ""'
                                + filename + '"" _Enter"')
                            Popen(
                                '"C:\Program Files\Rhinoceros 5 (64-bit)\System\Rhino.exe" /nosplash /runscript="_-open ""'
                                + filename + '"" _Enter"')
                        else:
                            rs.MessageBox(
                                'dxf cannot be openened automatically. Could not find:\nC:\Program Files\Rhinoceros 5 (64-bit)\System\Rhino.exe'
                            )

                    filename_stripped, file_extension = os.path.splitext(
                        filename)

                    if clamexdata:
                        with open(filename_stripped + '.txt', 'w') as the_file:
                            the_file.write('')

                        with open(filename_stripped + '.txt', 'a') as the_file:
                            for line in clamexdata:
                                str = 'CLAMEX POSX=%.3f POSY=%.3f RICHTING="%s"\n' % (
                                    line[0], line[1], line[2])
                                print str
                                the_file.write(str)

                    if result: print 'exported succesfully'

    rs.DeleteObjects(copies)

    if biesse_layers and len(biesse_layers) > 0:
        for layer in biesse_layers:
            rs.PurgeLayer(layer)

    rs.EnableRedraw(True)
Example #19
0
def RunCommand(is_interactive):
    if sc.escape_test(False):
        print "script cancelled"  #do something

    print "Making unique..."

    #******* Get blocks *****************
    #************************************

    objectIds = rs.GetObjects("Pick some blocks", 4096, preselect=True)
    if not objectIds:
        print "No objects"
        return False

    #pause viewport redraw
    rs.EnableRedraw(False)

    #******* Sort blocks by type ********
    #************************************
    blockTypes = {}
    for id in objectIds:
        blockName = rs.BlockInstanceName(id)
        if blockName not in blockTypes:
            blockTypes[blockName] = []
        blockTypes[blockName].append(id)

    #***** Define new block and add *****
    #************************************

    #Get block names
    blockNames = rs.BlockNames()

    #gather all new objects when done
    finalObjs = []

    for blockType in blockTypes:
        for id in blockTypes[blockType]:
            #Get the block transformation matrix and name
            blockXForm = rs.BlockInstanceXform(id)
            blockName = rs.BlockInstanceName(id)

            #Get objects in the block
            exObjs = rs.BlockObjects(blockName)

            #create new block name

            # if the string ends in digits m will be a Match object, or None otherwise.
            strippedName = re.sub(r'#[0-9]+$', '', blockName)

            #test if block name exist and add to the end number if true.
            x = 0
            tryAgain = True
            while tryAgain:
                x += 1
                newerBlockName = strippedName + "#" + str(x)
                if newerBlockName not in blockNames:
                    tryAgain = False
                    break

            #insert exObjs as new block
            rs.AddBlock(exObjs, [0, 0, 0], newerBlockName, delete_input=True)
            newerBlock = rs.InsertBlock(newerBlockName, [0, 0, 0])

            #match properties from original
            rs.MatchObjectAttributes(newerBlock, id)

            #transform new block
            rs.TransformObject(newerBlock, blockXForm)

            #append for final selection
            finalObjs.append(newerBlock)

        #add name to list of used blocknames.
        blockNames.append(newerBlockName)

    #Delete original block
    rs.DeleteObjects(objectIds)

    #Select all new objects
    rs.SelectObjects(finalObjs)

    rs.EnableRedraw(True)

    print "...aaand its done."
    #End RunCommand()

    #end sane
    return 0
def RunCommand(is_interactive):

    if '3GS' not in sc.sticky:
        compas_rhino.display_message('3GS has not been initialised yet.')
        return

    scene = sc.sticky['3GS']['scene']

    # get ForceVolMeshObject from scene
    objects = scene.find_by_name('force')
    if not objects:
        compas_rhino.display_message("There is no force diagram in the scene.")
        return
    force = objects[0]

    # get ForceVolMeshObject from scene
    objects = scene.find_by_name('form')
    if not objects:
        compas_rhino.display_message("There is no form diagram in the scene.")
        return
    form = objects[0]

    # check global constraints -------------------------------------------------

    force.check_eq()
    form.check_eq()

    if not force.settings['_is.valid'] or not form.settings['_is.valid']:
        options = ["Yes", "No"]
        option = compas_rhino.rs.GetString(
            "System is not in equilibrium... proceed?",
            strings=options,
            defaultString="No")
        if not option:
            return
        if option == "No":
            return

    show_loads = form.settings['show.loads']
    form.settings['show.loads'] = False

    # unified diagram ----------------------------------------------------------
    while True:

        rs.EnableRedraw(True)

        alpha = rs.GetReal('unified diagram scale', minimum=0.01, maximum=1.0)

        if alpha is None:
            break

        if not alpha:
            break

        compas_rhino.clear_layer(force.layer)
        compas_rhino.clear_layer(form.layer)

        # 1. get colors --------------------------------------------------------
        hf_color = (0, 0, 0)

        uv_c_dict = get_force_colors_uv(force.diagram,
                                        form.diagram,
                                        gradient=True)

        # 2. compute unified diagram geometries --------------------------------
        cells, prisms = volmesh_ud(force.diagram, form.diagram, scale=alpha)

        # 3. draw --------------------------------------------------------------
        for cell in cells:
            vertices = cells[cell]['vertices']
            faces = cells[cell]['faces']
            compas_rhino.draw_mesh(vertices,
                                   faces,
                                   layer=force.layer,
                                   name=str(cell),
                                   color=hf_color,
                                   redraw=False)

        for edge in prisms:
            vertices = prisms[edge]['vertices']
            faces = prisms[edge]['faces']
            compas_rhino.draw_mesh(vertices,
                                   faces,
                                   layer=force.layer,
                                   name=str(edge),
                                   color=uv_c_dict[edge],
                                   redraw=False)

        form.artist.draw_edges(color=uv_c_dict)

    form.settings['show.loads'] = show_loads

    scene.save()
Example #21
0
forcediagram = volmesh_from_polysurfaces(forcediagram, guids, '2f')
forcediagram.layer = layer_force
forcediagram.attributes['name'] = layer_force

forcediagram.draw()

# --------------------------------------------------------------------------
#  1. display boundary halffaces
# --------------------------------------------------------------------------
boundary_halffaces = forcediagram.halffaces_on_boundaries()

forcediagram.clear()
forcediagram.draw_edges()
forcediagram.draw_faces(faces=boundary_halffaces)

rs.EnableRedraw(True)

# --------------------------------------------------------------------------
#  2. select halfface and its dependents
# --------------------------------------------------------------------------
hf_inspector = VolmeshHalffaceInspector(forcediagram, dependents=True)
hf_inspector.enable()

hfkey = mesh_select_face(forcediagram)

hf_inspector.disable()

del hf_inspector

# ------------------------------------------------------------------------------
# 2. volmesh face pull
Example #22
0
from __future__ import absolute_import
Example #23
0
def Populate_Surfaces():
    #try:
    ###########################################################################
    #GET FUNCTIONS

    #GET INPUT SURFACE
    #srfs = rs.GetObjects('Select surface to populate', rs.filter.surface, True, True)
    #if srfs is None: return

    msg = "Select a surface or polysurface face to populate"
    srf_filter = rc.DocObjects.ObjectType.Surface
    res, srfObjs = rc.Input.RhinoGet.GetMultipleObjects(msg, False, srf_filter)
    if res != rc.Commands.Result.Success: return

    #Cleanup obj ref
    srfs = []
    for srf in srfObjs:
        if srf.GeometryComponentIndex < 0:
            face = srf.Surface()
        else:
            face = srf.Face()
        subSrf = face.ToNurbsSurface()
        srfs.append(subSrf)

    #GET POPULATION TYPE
    type = GetPopulationType(False)
    if type is None: return None

    #GET BLOCK NAMES
    if type == 'Custom Block':
        blockNames, blockIDs = GetCustomBlockNames()
    else:
        blockNames = GetBlockNames(type)
    if blockNames is None: return

    #GET NUMBER OF OBJECTS
    numObjects = GetNumObjects()
    if numObjects is None: return None

    ###########################################################################
    #Spacing
    if type == '2D People' or type == '3D People':
        spacing = 42
    elif type == '2D Trees':
        spacing = 100
    elif type == '3D Trees':
        spacing = 200
    else:
        spacing = GetCustomSpacing(blockNames[0])
    ###########################################################################

    #DRAW FUNCTIONS
    rs.EnableRedraw(False)

    #RANDOM PTS ON SURFACE
    pts = []
    for srf in srfs:
        pts.append(RandomPtsOnSrf(srf, numObjects))

    #RANDOM ANGLES
    angles = []
    for srf in srfs:
        angles.append(RandomAngles(numObjects))

    #ORIENT ANGLES AWAY FROM EDGES
    if type == '2D People' or type == '3D People':
        for i, srf in enumerate(srfs):
            angles[i] = OrientAwayFromEdges(pts[i], angles[i], srf, spacing)

    for i in range(0, 5):
        #CONGREGATE THE POINTS
        for j, srf in enumerate(srfs):
            pts[j] = Congregate(pts[j], spacing, 3)

            #MOVE AWAY FROM SURFACE EDGES
            pts[j] = MoveAwayFromEdges(pts[j], srf, spacing)

    #ORIENT ANGLES TOGETHER
    if type == '2D People' or type == '3D People':
        for i, srf in enumerate(srfs):
            angles[i] = AlignAngles(pts[i], angles[i], srf, spacing)

    upVec = rc.Geometry.Vector3d(0, 0, 1)
    scaleVariation = .1

    for i, srf in enumerate(srfs):
        for j, pt in enumerate(pts[i]):
            #Choose random angle
            angle = angles[i][j]

            thisIndex = random.randint(0, len(blockNames) - 1)
            thisBlockName = blockNames[thisIndex]

            if TryLoadBlock(type, thisBlockName):
                #xform = rs.BlockInstanceXform(blockIDs[thisIndex])
                eachBlock = rs.InsertBlock(thisBlockName,
                                           pt,
                                           angle_degrees=angle)
                #eachBlock = rs.InsertBlock2(thisBlockName, newXform)
                try:
                    if type == '2D People' or type == '3D People':
                        layerName = '2_ENTOURAGE::' + 'People'
                    elif type == '2D Trees':
                        layerName = '2_ENTOURAGE::' + 'Vegetation'
                    elif type == '3D Trees':
                        layerName = '2_ENTOURAGE::' + 'Vegetation'
                    elif type == '3D Vehicles':
                        layerName = '2_ENTOURAGE::' + 'Vehicles'
                    elif type == 'Custom Block':
                        layerName = rs.ObjectLayer(blockIDs[0])
                    else:
                        layerName = '2_ENTOURAGE'
                    rs.ObjectLayer(eachBlock, layerName)
                    xyScale = random.uniform(1 - scaleVariation,
                                             1 + scaleVariation)
                    zScale = random.uniform(1 - scaleVariation,
                                            1 + scaleVariation)
                    rs.ScaleObject(eachBlock, pt, (xyScale, xyScale, zScale))
                except:
                    pass

    rs.EnableRedraw(True)
Example #24
0
def editing_density(coarse_pseudo_quad_mesh):
    """Edit the density of a pattern via its strip densities.

    Parameters
    ----------
    coarse_pseudo_quad_mesh : CoarsePseudoQuadMesh
            The pattern to edit.

    """

    while True:

        # update drawing
        rs.EnableRedraw(False)
        artist = rhino_artist.MeshArtist(
            coarse_pseudo_quad_mesh.get_quad_mesh())
        guid = artist.draw_mesh()
        rs.EnableRedraw(True)

        # choose operation
        operation = rs.GetString(
            'edit strip density?',
            strings=[
                'global_density_value', 'global_subdivision_target_length',
                'strip_density_value', 'strip_subdivision_target_length',
                'global_uniform_target_number_faces', 'exit'
            ])

        # stop if asked
        if operation is None or operation == 'exit':
            rs.DeleteObjects(guid)
            break

        # get operation parameters
        if 'strip' in operation:
            skey = select_quad_mesh_strip(coarse_pseudo_quad_mesh,
                                          text='density')
            print(skey)
            print(coarse_pseudo_quad_mesh.data['attributes']['strips'])
        if 'value' in operation:
            d = rs.GetInteger('density value', number=3, minimum=1)
        elif 'length' in operation:
            t = rs.GetReal('density target', number=1.)
        elif 'faces' in operation:
            nb_faces = rs.GetInteger('density value', number=100, minimum=1)

        # apply operation
        if operation == 'strip_density_value':
            coarse_pseudo_quad_mesh.set_strip_density(skey, d)

        elif operation == 'global_density_value':
            coarse_pseudo_quad_mesh.set_strips_density(d)

        elif operation == 'strip_subdivision_target_length':
            coarse_pseudo_quad_mesh.set_strip_density_target(skey, t)

        elif operation == 'global_subdivision_target_length':
            coarse_pseudo_quad_mesh.set_strips_density_target(t)

        elif operation == 'global_uniform_target_number_faces':

            coarse_pseudo_quad_mesh.set_strips_density_equal_face_target(
                nb_faces)

        # update data
        coarse_pseudo_quad_mesh.densification()

        # delete drawing
        rs.DeleteObjects(guid)
Example #25
0
def stairHeight(route, width=48, height=120):
    """
    Makes a stair to specified height.

    input: route(pline), width (num), height(num)
    returns: Geo
    """
    try:
        rs.EnableRedraw(False)
        rs.SimplifyCurve(route)

        if route is None:
            print("ERROR: No path selected")
            return

        if (rs.UnitSystem() == 2):  #if mm
            maxRiserHeight = 180
            thickness = 200
        if (rs.UnitSystem() == 4):  #if m
            maxRiserHeight = .180
            thickness = .200
        if (rs.UnitSystem() == 8):  #if in"
            maxRiserHeight = 7
            thickness = 9

        negativeBoo = False
        if (height < 0):
            #if the stair
            negativeBoo = True
        landingEdges = []
        landings = []
        segments = rs.ExplodeCurves(route)
        if len(segments) < 1:
            segments = [rs.CopyObject(route)]
        landingHeight = []
        geometry = []

        #Check that all segments are lines
        for i in range(0, len(segments)):
            if not (rs.IsLine(segments[i])):
                print(
                    "ERROR: This function only accepts lines. No arcs or nurb curves."
                )
                rs.DeleteObjects(segments)
                return

        #first landing edge
        norm = rs.VectorRotate(rs.CurveTangent(segments[0], 0), 90, [0, 0, 1])
        norm = rs.VectorScale(rs.VectorUnitize(norm), width / 2)
        side1Pt = rs.VectorAdd(rs.CurveStartPoint(segments[0]), norm)
        side2Pt = rs.VectorAdd(rs.CurveStartPoint(segments[0]), -norm)
        landingEdges.append(rs.AddLine(side1Pt, side2Pt))

        #middle landing edges
        for i in range(0, len(segments) - 1):
            edgeList, landing = rampIntersection(segments[i], segments[i + 1],
                                                 width)
            landingEdges.append(edgeList[0])
            landingEdges.append(edgeList[1])
            landings.append(landing)

        #last landing edge
        norm = rs.VectorRotate(
            rs.CurveTangent(segments[-1], rs.CurveParameter(segments[-1], 1)),
            90, [0, 0, 1])
        norm = rs.VectorScale(rs.VectorUnitize(norm), width / 2)
        side1Pt = rs.VectorAdd(rs.CurveEndPoint(segments[-1]), norm)
        side2Pt = rs.VectorAdd(rs.CurveEndPoint(segments[-1]), -norm)
        landingEdges.append(rs.AddLine(side1Pt, side2Pt))

        #Add risers
        riserCrvs = []
        treadVecs = []
        numRisersPerRun = []
        numRisers = abs(int(math.ceil(height / maxRiserHeight)))
        risersSoFar = 0
        totalRun = getTotalRun(landingEdges)
        optTreadDepth = totalRun / (numRisers - 1)
        #2R+T = 635
        riserHeight = height / numRisers
        if (negativeBoo):
            curRiserHeight = 0
        else:
            curRiserHeight = riserHeight
        for i in range(0, len(landingEdges), 2):  #find numRisers in each run
            a = rs.CurveMidPoint(landingEdges[i])
            b = rs.CurveMidPoint(landingEdges[i + 1])
            runDist = rs.Distance(a, b)
            numRisersThisRun = int(round((runDist / optTreadDepth), 0))
            if (numRisersThisRun == 0):
                numRisersThisRun = 1
            if (i == len(landingEdges) -
                    2):  #if last run, add the rest of the risers
                numRisersThisRun = numRisers - risersSoFar
            else:
                risersSoFar = risersSoFar + numRisersThisRun
            numRisersPerRun.append(numRisersThisRun)

        #Create Risers on Plan
        for i in range(0, len(landingEdges), 2):
            run = []
            a = rs.CurveMidPoint(landingEdges[i])
            b = rs.CurveMidPoint(landingEdges[i + 1])
            centerStringer = rs.AddLine(a, b)
            runDist = rs.Distance(a, b)
            numRisersThisRun = numRisersPerRun[int(i / 2)]  #risers in this run
            tarPts = rs.DivideCurve(centerStringer,
                                    numRisersThisRun,
                                    create_points=False)
            rs.DeleteObject(centerStringer)
            for j in range(0, numRisersThisRun + 1):
                if (j == 0):
                    treadVecs.append(rs.VectorCreate(tarPts[0], tarPts[1]))
                transVec = rs.VectorCreate(tarPts[0], tarPts[j])
                run.append(rs.CopyObject(landingEdges[i], -transVec))
            riserCrvs.append(run)
            print('Flight {0} has {1} risers: {3}" tall, Treads: {2}" deep'.
                  format(
                      int(i / 2) + 1, numRisersThisRun,
                      rs.VectorLength(treadVecs[int(i / 2)]), riserHeight))
        #Move riser edges vertically
        for i in range(0, len(riserCrvs)):
            triangles = []
            if (negativeBoo):
                for j in range(0, len(riserCrvs[i]) - 1):
                    #if stairs descending
                    rs.MoveObject(
                        riserCrvs[i][j],
                        rs.VectorAdd([0, 0, curRiserHeight], -treadVecs[i]))
                    riserGeo = rs.ExtrudeCurveStraight(riserCrvs[i][j],
                                                       [0, 0, 0],
                                                       [0, 0, riserHeight])
                    treadGeo = rs.ExtrudeCurveStraight(riserCrvs[i][j],
                                                       [0, 0, 0], treadVecs[i])
                    stPt = rs.AddPoint(rs.CurveStartPoint(riserCrvs[i][j]))
                    pt1 = rs.CopyObject(
                        stPt, [0, 0, riserHeight])  #first riser in run
                    pt2 = rs.CopyObject(stPt, treadVecs[i])  #last riser in run
                    triCrv = rs.AddPolyline([stPt, pt1, pt2, stPt])
                    triangles.append(rs.AddPlanarSrf(triCrv))
                    geometry.append(riserGeo)  #riser
                    geometry.append(treadGeo)  #tread
                    curRiserHeight = curRiserHeight + riserHeight
                    rs.MoveObject(riserCrvs[i][j], treadVecs[i])
                    #cleanup
                    rs.DeleteObject(triCrv)
                    rs.DeleteObject(stPt)
                    rs.DeleteObject(pt1)
                    rs.DeleteObject(pt2)
            else:
                for j in range(0, len(riserCrvs[i]) - 1):
                    #if stairs ascend
                    rs.MoveObject(riserCrvs[i][j], [0, 0, curRiserHeight])
                    stPt = rs.AddPoint(rs.CurveStartPoint(riserCrvs[i][j]))
                    pt1 = rs.CopyObject(
                        stPt, [0, 0, -riserHeight])  #first riser in run
                    pt2 = rs.CopyObject(stPt,
                                        -treadVecs[i])  #last riser in run
                    triCrv = rs.AddPolyline([stPt, pt1, pt2, stPt])
                    triangles.append(rs.AddPlanarSrf(triCrv))
                    riserGeo = rs.ExtrudeCurveStraight(riserCrvs[i][j],
                                                       [0, 0, 0],
                                                       [0, 0, -riserHeight])
                    treadGeo = rs.ExtrudeCurveStraight(riserCrvs[i][j],
                                                       [0, 0, 0],
                                                       -treadVecs[i])
                    geometry.append(riserGeo)  #riser
                    geometry.append(treadGeo)  #tread
                    curRiserHeight = curRiserHeight + riserHeight
                    #cleanup
                    rs.DeleteObject(triCrv)
                    rs.DeleteObject(stPt)
                    rs.DeleteObject(pt1)
                    rs.DeleteObject(pt2)

            #Make Stringer
            if (negativeBoo):
                firstStartPt = rs.AddPoint(rs.CurveStartPoint(riserCrvs[i][0]))
                lastStartPt = rs.AddPoint(rs.CurveStartPoint(riserCrvs[i][-2]))
                #rs.MoveObject(firstStartPt, [0,0,riserHeight]) #first riser in run
                rs.MoveObject(lastStartPt, -treadVecs[i])  #last riser in run
                rs.MoveObject(lastStartPt,
                              [0, 0, riserHeight])  #last riser in run
            else:
                firstStartPt = rs.AddPoint(rs.CurveStartPoint(riserCrvs[i][0]))
                lastStartPt = rs.AddPoint(rs.CurveStartPoint(riserCrvs[i][-2]))
                rs.MoveObject(firstStartPt,
                              [0, 0, -riserHeight])  #first riser in run
                rs.MoveObject(lastStartPt, -treadVecs[i])  #last riser in run
            stringerCrv = rs.AddLine(firstStartPt, lastStartPt)
            stringerSrf = rs.ExtrudeCurveStraight(stringerCrv, [0, 0, 0],
                                                  [0, 0, -thickness])
            triangles.append(stringerSrf)
            stringer = makeFace(triangles)
            stringerVec = rs.VectorCreate(rs.CurveEndPoint(riserCrvs[i][0]),
                                          rs.CurveStartPoint(riserCrvs[i][0]))
            underside = rs.ExtrudeCurveStraight(
                stringerCrv, rs.CurveStartPoint(riserCrvs[i][0]),
                rs.CurveEndPoint(riserCrvs[i][0]))
            geometry.append(rs.MoveObject(underside, [0, 0, -thickness]))
            geometry.append(rs.CopyObject(stringer, stringerVec))
            geometry.append(stringer)

            #cleanup
            rs.DeleteObject(firstStartPt)
            rs.DeleteObject(lastStartPt)
            rs.DeleteObject(stringerCrv)
            rs.DeleteObject(stringerSrf)

        #Move Landings
        lastLandingHeight = 0
        for i in range(0, len(segments) - 1):
            landingHeight = lastLandingHeight + numRisersPerRun[i] * riserHeight
            rs.MoveObject(landings[i], [0, 0, landingHeight])
            landingTopSrf = rs.AddPlanarSrf(landings[i])
            landingBtmSrf = rs.CopyObject(landingTopSrf, [0, 0, -thickness])
            geometry.append(landingTopSrf)
            geometry.append(landingBtmSrf)
            lastLandingHeight = landingHeight
            landingEdgesToEx = rs.ExplodeCurves(landings[i])
            geometry.append(
                rs.ExtrudeCurveStraight(landingEdgesToEx[1], [0, 0, 0],
                                        [0, 0, -thickness]))
            geometry.append(
                rs.ExtrudeCurveStraight(landingEdgesToEx[2], [0, 0, 0],
                                        [0, 0, -thickness]))
            rs.DeleteObjects(landingEdgesToEx)

        #Create final geometry
        joinedGeo = rs.JoinSurfaces(geometry, True)
        holes = rs.DuplicateSurfaceBorder(joinedGeo)
        cap = rs.AddPlanarSrf(holes)
        newGeo = rs.ExplodePolysurfaces(joinedGeo, True)
        for i in cap:
            newGeo.append(i)
        FinalGeo = rs.JoinSurfaces(newGeo, True)

        #cleanup
        try:
            rs.DeleteObjects(segments)
        except:
            rs.DeleteObject(segments)
        rs.DeleteObjects(holes)
        rs.DeleteObjects(landings)
        rs.DeleteObjects(landingEdges)
        for i in riserCrvs:
            rs.DeleteObjects(i)

        rs.EnableRedraw(True)
        return FinalGeo
    except:
        print "Error"
        return None
Example #26
0
def editing_geometry_smoothing(coarse_pseudo_quad_mesh):
    """Edit the geometry of a pattern with smoothing.

    Parameters
    ----------
    coarse_pseudo_quad_mesh : CoarsePseudoQuadMesh
            The pattern to edit.

    """

    mesh_to_smooth = rs.GetString('mesh to smooth?',
                                  strings=[
                                      'coarse_pseudo_quad_mesh',
                                      'pseudo_quad_mesh', 'polygonal_mesh'
                                  ])
    if mesh_to_smooth == 'coarse_pseudo_quad_mesh':
        mesh = coarse_pseudo_quad_mesh
    elif mesh_to_smooth == 'pseudo_quad_mesh':
        mesh = coarse_pseudo_quad_mesh.get_quad_mesh
    elif mesh_to_smooth == 'polygonal_mesh':
        mesh = coarse_pseudo_quad_mesh.get_polygonal_mesh()
    else:
        return 0

    settings = {'iterations': 50, 'damping': .5, 'constraints': {}}

    while True:

        rs.EnableRedraw(False)
        artist = rhino_artist.MeshArtist(mesh)
        guid = artist.draw_mesh()
        rs.EnableRedraw(True)

        operation = rs.GetString(
            'edit smoothing settings?',
            strings=['smooth', 'iterations', 'damping', 'constraints', 'exit'])

        if operation is None or operation == 'exit':
            if type(guid) == list:
                rs.DeleteObjects(guid)
            else:
                rs.DeleteObject(guid)
            break

        elif operation == 'iterations':
            settings[operation] = rs.GetInteger('iterations',
                                                number=settings[operation],
                                                minimum=0)

        elif operation == 'damping':
            settings[operation] = rs.GetReal('damping',
                                             number=settings[operation],
                                             minimum=0.,
                                             maximum=1.)

        elif operation == 'constraints':
            count = 100
            while count:
                count -= 1
                guids = display_smoothing_constraints(mesh,
                                                      settings[operation])
                constraint_type = rs.GetString('type of constraints?',
                                               strings=[
                                                   'automated_from_surface',
                                                   'automated_from_objects',
                                                   'customised', 'reset',
                                                   'exit'
                                               ])
                rs.DeleteObjects(guids)
                if constraint_type == 'automated_from_surface':
                    settings[
                        operation] = automated_smoothing_surface_constraints(
                            mesh,
                            RhinoSurface(
                                rs.GetObject('surface constraints', filter=8)))
                elif constraint_type == 'automated_from_objects':
                    object_constraints = rs.GetObjects('object constraints')
                    point_constraints = [
                        obj for obj in object_constraints
                        if rs.ObjectType(obj) == 1
                    ]
                    curve_constraints = [
                        obj for obj in object_constraints
                        if rs.ObjectType(obj) == 4
                    ]
                    surface_constraint = [
                        obj for obj in object_constraints
                        if rs.ObjectType(obj) == 8
                    ]
                    if len(surface_constraint) > 1:
                        print(
                            'More than one surface constraint! Only the first one is taken into account.'
                        )
                    if len(surface_constraint) == 0:
                        surface_constraint = None
                    else:
                        surface_constraint = surface_constraint[0]
                    settings[operation] = automated_smoothing_constraints(
                        mesh, point_constraints, curve_constraints,
                        surface_constraint)
                elif constraint_type == 'customised':
                    settings[operation] = customized_smoothing_constraints(
                        mesh, settings[operation])
                elif constraint_type == 'reset':
                    artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
                    artist.clear_layer()
                    artist.draw_vertices()
                    artist.redraw()
                    vkeys = rhino_helper.mesh_select_vertices(
                        mesh, message='vertices')
                    if vkeys is None:
                        vkeys = list(mesh.vertices())
                    artist.clear_layer()
                    artist.redraw()
                    rs.DeleteLayer('mesh_artist')
                    for vkey in vkeys:
                        if vkey in settings[operation]:
                            del settings[operation][vkey]
                else:
                    break

        elif operation == 'smooth':
            constrained_smoothing(mesh,
                                  kmax=settings['iterations'],
                                  damping=settings['damping'],
                                  constraints=settings['constraints'],
                                  algorithm='area')

        if type(guid) == list:
            rs.DeleteObjects(guid)
        else:
            rs.DeleteObject(guid)

    if mesh_to_smooth == 'coarse_pseudo_quad_mesh':
        coarse_pseudo_quad_mesh = mesh
    elif mesh_to_smooth == 'pseudo_quad_mesh':
        coarse_pseudo_quad_mesh.set_quad_mesh(mesh)
        coarse_pseudo_quad_mesh.set_polygonal_mesh(mesh.copy())
    elif mesh_to_smooth == 'polygonal_mesh':
        coarse_pseudo_quad_mesh.set_polygonal_mesh(mesh)
def editing_primal_dual(primal, default_settings, curve_constraints,
                        point_constraints):

    dx = default_settings['dx']
    dy = default_settings['dy']
    density = default_settings['density']
    pattern = default_settings['pattern']
    smoothing_iterations = default_settings['smoothing iterations']
    smoothing_damping = default_settings['smoothing damping']

    # grammar rules + propagation scheme
    rules = [
        'settings', 'face_opening', 'flat_corner_2', 'flat_corner_3',
        'flat_corner_33', 'split_35', 'split_35_diag', 'split_26',
        'simple_split', 'double_split', 'singular_boundary_1',
        'singular_boundary_2', 'clear_faces', 'move_vertices', 'stop'
    ]

    primal_guid = draw_mesh(primal)

    dense_primal = densification(primal, 1, custom=False)

    # smooth
    rs.EnableRedraw(False)
    constraints = {}
    for pt in point_constraints:
        vertex = None
        min_dist = -1
        for vkey in dense_primal.vertices_on_boundary():
            dist = distance_point_point(rs.PointCoordinates(pt),
                                        dense_primal.vertex_coordinates(vkey))
            if min_dist < 0 or min_dist > dist:
                vertex = vkey
                min_dist = dist
        constraints[vertex] = ('point', rs.PointCoordinates(pt))
    for vkey in dense_primal.vertices_on_boundary():
        if vkey not in constraints:
            curve = None
            min_dist = -1
            for crv in curve_constraints:
                vkey_guid = rs.AddPoint(dense_primal.vertex_coordinates(vkey))
                t = rs.CurveClosestPoint(crv, vkey_guid)
                pt = rs.EvaluateCurve(crv, t)
                dist = distance_point_point(
                    pt, dense_primal.vertex_coordinates(vkey))
                rs.DeleteObject(vkey_guid)
                if min_dist < 0 or min_dist > dist:
                    curve = crv
                    min_dist = dist
            constraints[vkey] = ('curve', curve)
    rs.EnableRedraw(True)

    mesh_smooth_area(dense_primal,
                     kmax=smoothing_iterations,
                     damping=smoothing_damping,
                     callback=apply_constraints,
                     callback_args=[dense_primal, constraints])

    dense_primal_guid = draw_mesh(dense_primal)
    rs.MoveObject(dense_primal_guid, [dx, 0, 0])

    dense_dual = mesh_dual(dense_primal, Mesh)
    rotate_mesh(dense_dual, pi / 2)
    rs.EnableRedraw(False)
    dense_dual_guid = draw_mesh(dense_dual)
    rs.MoveObject(dense_dual_guid, [2 * dx, 0, 0])
    rs.EnableRedraw(True)

    # start editing
    count = 1000
    while count > 0:
        count -= 1

        primal.update_default_edge_attributes()

        #ask for rule
        rule = rs.GetString('rule?', strings=rules)

        # exit
        if rule == 'stop':
            break

        elif rule == 'settings':
            density, pattern, dx, dy, smoothing_iterations, smoothing_damping = rs.PropertyListBox(
                [
                    'density', 'pattern', 'dx', 'dy', 'smoothing iterations',
                    'smoothing damping'
                ], [
                    density, pattern, dx, dy, smoothing_iterations,
                    smoothing_damping
                ],
                title='settings')
            density = float(density)
            dx = float(dx)
            dy = float(dy)
            smoothing_iterations = int(smoothing_iterations)
            smoothing_damping = float(smoothing_damping)

        # apply editing rule
        elif rule in rules:
            regular_vertices = list(primal.vertices())
            apply_rule(primal, rule)
            #if rule != 'clear_faces':
            mesh_propagation(primal, regular_vertices)

        rs.DeleteObjects(primal_guid)
        rs.DeleteObjects(dense_primal_guid)
        rs.DeleteObjects(dense_dual_guid)

        primal_guid = draw_mesh(primal)

        for fkey in primal.faces():
            if len(primal.face_vertices(fkey)) != 4:
                rs.AddPoint(primal.face_centroid(fkey))

        dense_primal = densification(primal, density, custom=False)
        dense_primal = dense_primal.to_mesh()
        dense_primal = patterning(dense_primal, pattern)
        to_del = [
            vkey for vkey in dense_primal.vertices()
            if len(dense_primal.vertex_neighbours(vkey)) == 0
        ]
        for vkey in to_del:
            del dense_primal.vertex[vkey]

        # smooth
        rs.EnableRedraw(False)
        constraints = {}
        for pt in point_constraints:
            vertex = None
            min_dist = -1
            for vkey in dense_primal.vertices_on_boundary():
                dist = distance_point_point(
                    rs.PointCoordinates(pt),
                    dense_primal.vertex_coordinates(vkey))
                if min_dist < 0 or min_dist > dist:
                    vertex = vkey
                    min_dist = dist
            constraints[vertex] = ('point', rs.PointCoordinates(pt))
        for vkey in dense_primal.vertices_on_boundary():
            if vkey not in constraints:
                curve = None
                min_dist = -1
                for crv in curve_constraints:
                    vkey_guid = rs.AddPoint(
                        dense_primal.vertex_coordinates(vkey))
                    t = rs.CurveClosestPoint(crv, vkey_guid)
                    pt = rs.EvaluateCurve(crv, t)
                    dist = distance_point_point(
                        pt, dense_primal.vertex_coordinates(vkey))
                    rs.DeleteObject(vkey_guid)
                    if min_dist < 0 or min_dist > dist:
                        curve = crv
                        min_dist = dist
                constraints[vkey] = ('curve', curve)
        rs.EnableRedraw(True)

        mesh_smooth_area(dense_primal,
                         kmax=smoothing_iterations,
                         damping=smoothing_damping,
                         callback=apply_constraints,
                         callback_args=[dense_primal, constraints])

        rs.EnableRedraw(False)
        dense_primal_guid = draw_mesh(dense_primal)
        rs.MoveObject(dense_primal_guid, [dx, 0, 0])
        rs.EnableRedraw(True)

        dense_dual = mesh_dual(dense_primal, Mesh)
        rotate_mesh(dense_dual, pi / 2)
        rs.EnableRedraw(False)
        dense_dual_guid = draw_mesh(dense_dual)
        rs.MoveObject(dense_dual_guid, [2 * dx, 0, 0])
        rs.EnableRedraw(True)

    return primal, dense_primal, dense_dual
Example #28
0
def singular():
    """Explore a pattern, its topology (singularities, densities and symmetries) and its geoemtry (via smoothing).

    """

    layer = rs.CurrentLayer()

    pattern_from = rs.GetString('start pattern from?',
                                strings=[
                                    'coarse_pseudo_quad_mesh',
                                    'pseudo_quad_mesh', 'surface_and_features'
                                ])

    if pattern_from == 'coarse_pseudo_quad_mesh':
        guid = rs.GetObject('get coarse quad mesh', filter=32)
        vertices, faces = RhinoMesh.from_guid(guid).get_vertices_and_faces()
        clean_faces(faces)
        poles = []
        #print(faces)
        for face in faces:
            if len(face) != 4:
                poles = [
                    rs.PointCoordinates(point)
                    for point in rs.GetObjects('get pole points', filter=1)
                ]
                break
        coarse_pseudo_quad_mesh = CoarsePseudoQuadMesh.from_vertices_and_faces_with_poles(
            vertices, faces, poles)
        coarse_pseudo_quad_mesh.collect_strips()
        print(coarse_pseudo_quad_mesh.data['attributes']['strips'])
        coarse_pseudo_quad_mesh.set_strips_density(1)
        coarse_pseudo_quad_mesh.set_quad_mesh(coarse_pseudo_quad_mesh.copy())
        coarse_pseudo_quad_mesh.set_polygonal_mesh(
            coarse_pseudo_quad_mesh.copy())
        print(coarse_pseudo_quad_mesh.data['attributes']['strips'])
    elif pattern_from == 'pseudo_quad_mesh':
        guid = rs.GetObject('get quad mesh', filter=32)
        vertices, faces = RhinoMesh.from_guid(guid).get_vertices_and_faces()
        clean_faces(faces)
        poles = []
        for face in faces:
            if len(face) != 4:
                poles = [
                    rs.PointCoordinates(point)
                    for point in rs.GetObjects('get pole points', filter=1)
                ]
                break
        coarse_pseudo_quad_mesh = CoarsePseudoQuadMesh.from_quad_mesh(
            PseudoQuadMesh.from_vertices_and_faces_with_poles(
                vertices, faces, poles))
    elif pattern_from == 'surface_and_features':
        srf_guid = rs.GetObject('get surface', filter=8)
        crv_guids = rs.GetObjects('get optional curve features', filter=4)
        if crv_guids is None:
            crv_guids = []
        pt_guids = rs.GetObjects('get optional point features', filter=1)
        if pt_guids is None:
            pt_guids = []
        coarse_pseudo_quad_mesh = surface_decomposition(
            srf_guid,
            rs.GetReal('precision', number=1.),
            crv_guids=crv_guids,
            pt_guids=pt_guids,
            output_skeleton=False)[0]
        coarse_pseudo_quad_mesh.collect_strips()
        coarse_pseudo_quad_mesh.set_strips_density(1)
        coarse_pseudo_quad_mesh.set_quad_mesh(coarse_pseudo_quad_mesh.copy())
        coarse_pseudo_quad_mesh.set_polygonal_mesh(
            coarse_pseudo_quad_mesh.copy())
        artist = rhino_artist.MeshArtist(coarse_pseudo_quad_mesh)
        guid = artist.draw_mesh()
    else:
        return 0

    while True:

        #edit = rs.GetString('edit pattern?', strings = ['topology', 'density', 'symmetry', 'geometry', 'evaluate', 'exit'])
        edit = rs.GetString('edit pattern?',
                            strings=[
                                'topology', 'density', 'symmetry', 'geometry',
                                'save', 'exit'
                            ])

        if type(guid) == list:
            rs.DeleteObjects(guid)
        else:
            rs.DeleteObject(guid)

        if edit is None or edit == 'exit':
            rs.EnableRedraw(False)
            artist = rhino_artist.MeshArtist(
                coarse_pseudo_quad_mesh.get_polygonal_mesh())
            return artist.draw_mesh()

        if edit == 'topology':
            editing_topology(coarse_pseudo_quad_mesh)
            coarse_pseudo_quad_mesh.densification()
            coarse_pseudo_quad_mesh.set_polygonal_mesh(
                coarse_pseudo_quad_mesh.get_quad_mesh().copy())

        elif edit == 'density':
            editing_density(coarse_pseudo_quad_mesh)
            coarse_pseudo_quad_mesh.set_polygonal_mesh(
                coarse_pseudo_quad_mesh.get_quad_mesh().copy())

        elif edit == 'symmetry':
            editing_symmetry(coarse_pseudo_quad_mesh)

        elif edit == 'geometry':
            editing_geometry(coarse_pseudo_quad_mesh)

        rs.EnableRedraw(False)
        artist = rhino_artist.MeshArtist(
            coarse_pseudo_quad_mesh.get_polygonal_mesh())
        guid = artist.draw_mesh()
        rs.EnableRedraw(True)

        if edit == 'save':
            save_design(coarse_pseudo_quad_mesh, layer)

        if edit == 'evaluate':
            evaluate_pattern(coarse_pseudo_quad_mesh.get_polygonal_mesh())
# Falola Yusuf, Github: falfat
# import necessary modules
import rhinoscriptsyntax as rs
import DFN_Gen
import Domain
import Input
import DFN_Gen
import Frac
import scriptcontext as sc

#sc.doc.Objects.Clear()

#Avoid drawing whilst computing
rs.EnableRedraw(False)

#read fracture network data
data = "DataFile.txt"
radius, boxlength, n, fracture_shape = Input.ReadFile(data)

#create an instance of domain
dom = Domain.Domain(boxlength)

#draw domain
dom.Show()

#insert n fractures in the domain
frac_list = DFN_Gen.FixedFractureGen(n)

#trims fractures outside the domain
dom.RemoveSurfacesOutsideOfBox(dom.length)
Example #30
0
def hatchedCurve():
    """
    this script divides a curve by length and makes a hatch-dashed version of it'
    works only in world top
    version 1.1
    www.studiogijs.nl
    """

    projection = Rhino.Geometry.Vector3d(0, 0, 1)
    viewprojection = sc.doc.Views.ActiveView.ActiveViewport.CameraZ
    if not viewprojection == projection:
        print " this script only works in top view"
        return
    getcurves = rs.GetObjects(
        "select curves to change into hatch-dashed-style", 4, preselect=True)
    rs.UnselectAllObjects()
    if not getcurves:
        return

    s = sc.sticky['scale'] if sc.sticky.has_key('scale') else 1
    scale = rs.GetReal("line-width of the hatch-dashed curve", s, .5, 5)

    if not scale:
        return
    sc.sticky['scale'] = scale

    f = sc.sticky['factor'] if sc.sticky.has_key('factor') else 5
    factor = rs.GetReal("line-length factor of the hatch-dashed curve", f, 1,
                        10)

    if not factor:
        return
    sc.sticky['factor'] = factor

    #turn of the lights, magic should be done in darkness
    rs.EnableRedraw(False)

    style = Rhino.Geometry.CurveOffsetCornerStyle.Sharp
    tol = sc.doc.ModelAbsoluteTolerance
    plane = Rhino.Geometry.Plane.WorldXY

    subcurvelist = []
    offset_curves = []
    for curve in getcurves:
        # ------------------------------------------------------
        # offset curves inward and outward to create the borders
        # ------------------------------------------------------
        c = rs.coercecurve(curve)
        if not rs.IsCurvePlanar(curve):
            continue
        #else:
        #rs.HideObject(curve)

        offsets = c.Offset(plane, scale / 2, tol, style)
        if offsets:
            offset = sc.doc.Objects.Add(offsets[0])
            offset_curves.append(offset)
        offsets = c.Offset(plane, -scale / 2, tol, style)
        if offsets:
            offset = sc.doc.Objects.Add(offsets[0])
            offset_curves.append(offset)
        # -----------------------------------
        # explode c into segments if possible
        # -----------------------------------
        exploded = rs.ExplodeCurves(c)
        if exploded:
            for segment in exploded:
                subcurvelist.append(segment)
        else:
            #it appears this is for single lines only
            subcurvelist.append(rs.CopyObject(curve))

    segments = []
    # -------------------------------------------------------
    # divide subcurves into shorter segments (dashed pattern)
    # -------------------------------------------------------
    for curve in subcurvelist:
        closed = False
        if rs.coercecurve(curve).IsClosed:
            closed = True
        if rs.CurveLength(curve) > (scale * factor):
            segment_count = int(rs.CurveLength(curve) / (scale * factor / 2))
            while True:
                #we need to start with 1/2 segment, then full space, then half segment
                #so #of segments needs to be a multiple of 4
                if segment_count % 4 == 0: break
                else: segment_count += 1

            pts = rs.DivideCurve(curve, segment_count)

            if closed:
                pts = pts[
                    1:]  #remove only first point, since last point == first
            pts = pts[1:-1]  #remove first and last point

            pts = pts[::2]  #remove every other point
            # --------------
            # dash the curve
            # --------------
            for i, pt in enumerate(pts):
                t = rs.CurveClosestPoint(curve, pt)
                curves = rs.SplitCurve(curve, t)
                curve = curves[1]
                segment = curves[0]
                if closed:
                    #delete every odd segment
                    if i % 2 == 0:
                        rs.DeleteObject(segment)
                    else:
                        segments.append(segment)
                else:
                    #delete every even segment
                    if i % 2 == 1:
                        rs.DeleteObject(segment)
                    else:
                        segments.append(segment)

            #append the remaining part
            segments.append(curve)

    def hatchthis(s):

        #offset all segments
        s = rs.coercecurve(s)
        offsets = s.Offset(plane, scale / 2, tol, style)
        if offsets:
            p1, p2, curve1 = getPointsAndLines(offsets)
        offsets = s.Offset(plane, -scale / 2, tol, style)
        if offsets:
            p3, p4, curve2 = getPointsAndLines(offsets)
        if not (p1 and p2 and p3 and p4):
            return

        #create end lines between the two offset curves
        line1 = rs.AddLine(p1, p3)
        line2 = rs.AddLine(p2, p4)
        polyline = rs.JoinCurves([line1, line2, curve1, curve2], True, tol)

        # FINALLY: hatch the bloody thing
        hatch = rs.AddHatch(polyline, 'Solid')

        #clean up
        rs.DeleteObject(polyline)

        return hatch

    if segments:
        segments = rs.JoinCurves(segments, True)
        layer = "hatched_curves"
        if not rs.IsLayer(layer):
            rs.AddLayer(layer)

        hatches = []
        #create the hatches
        for s in segments:
            rs.ObjectLayer(hatchthis(s), layer)
        for offset in offset_curves:
            rs.ObjectLayer(offset, layer)

    #clean up
    rs.DeleteObjects(segments)
    rs.HideObjects(getcurves)
    rs.DeleteObjects(curves)
    #put on the lights, it's the result that counts
    rs.EnableRedraw(True)