Hi All,
Is there someone who can edit the first python script so that you can preview the result before baking? similar to the 2nd python script. Thanks!
1st: Quick Bom Generation from CSV.gh (8.7 KB)
2nd:
DataGrid_test.gh (12.2 KB)
Hi All,
Is there someone who can edit the first python script so that you can preview the result before baking? similar to the 2nd python script. Thanks!
1st: Quick Bom Generation from CSV.gh (8.7 KB)
2nd:
DataGrid_test.gh (12.2 KB)
Have you asked JWalton or Florian, the respective authors of those scripts?
Quick Bom Generation from CSV.gh
"""Provides a scripting component.
Inputs:
x: The x script variable
y: The y script variable
Output:
a: The a output variable"""
__author__ = "JWalton"
__version__ = "2019.11.28"
import rhinoscriptsyntax as rs
import Rhino
import Rhino as rc
import scriptcontext as sc
import Rhino.Geometry as rg
from operator import itemgetter
# Set the script context to the current Rhino doc
sc.doc = rc.RhinoDoc.ActiveDoc
def CSVBom():
listA = _csv
#a = listA
plane=Rhino.Geometry.Plane.WorldXY
ListTotals = []
table = _pointFeed
rs.EnableRedraw(False)
ListLarge = []
ListLen = []
a=0
for row in listA:
row = row.split(";")
rowA = []
for str in row:
str = str.replace("\n","")
rowA.append(str)
rowB = []
for aa in rowA:
rowB=aa.split(',')
if len(rowB)<= len(rowA):rowB=rowA
list=[]
A=len(rowB)
ListLen.append(A)
for txt in rowB:
if txt :
test = rs.AddText(txt, plane, height=_textSize, font='Arial', font_style=0, justification=None)
bb = rs.BoundingBox(test, plane, in_world_coords=True)
if bb :
large =round(( bb[1].DistanceTo(bb[0])),1)
if large < 0: largeur=large*(-1)
list.append(large)
rs.DeleteObject(test)
else :
large=0.0
list.append(large)
else :
large=0.0
list.append(large)
ListLarge.append(list)
N = max(ListLen)
d_max = {i: max(map(itemgetter(i), ListLarge)) for i in range(N)}
#Largest
ListMax = d_max.values()
#Layers
rs.AddLayer("Name")
rs.AddLayer("Detail Lines",parent="Name")
rs.AddLayer("Texts",parent="Name")
listB = _csv
Group=rs.AddGroup()
ListGroup = []
H = _textSize
font='Arial'
count=1
for row in listB:
V=0
Y=0
row = row.split(";")
rowA = []
for str in row:
str = str.replace("\n","")
rowA.append(str)
rowB = []
for aa in rowA:
rowB=aa.split(',')
if len(rowB)<= len(rowA):rowB=rowA
for value in rowB:
#text placement
placeA= ((-H*2) - (float(count)*(H*2)))
placeB= ((-H) - (float(count)*(H*2)))
#rectangle
LX = (ListMax[Y])+(H*.25+H)
recA=rs.AddRectangle(plane,LX,H*2)
VV=V+(LX/2)
recA=rs.MoveObject(recA,[V,placeA,0.0])
rs.ObjectLayer(recA,"Detail Lines")
ListGroup.append(recA)
#text
txt=value
if txt :
txtA=rs.AddText (txt,plane,H,font,0,2 + 131072)
txtA=rs.MoveObject(txtA,[VV,placeB,0.0])
rs.ObjectLayer(txtA,"Texts")
ListGroup.append(txtA)
#new text placement
Y=Y+1
V=V+LX
#New Line
count=count+1
ListGroup=rs.MoveObjects(ListGroup,table)
# rs.EnableRedraw(True)
rs.AddObjectsToGroup(ListGroup,Group)
if x:
CSVBom()
# Then set the script context back to the Grasshopper doc
sc.doc = ghdoc
DataGrid_test.gh
"""Provides a scripting component.
Inputs:
x: The x script variable
y: The y script variable
Output:
a: The a output variable"""
__author__ = "Florian"
__version__ = "2020.02.06"
import Rhino as rh
import scriptcontext as sc
import ghpythonlib as gh
vec = rh.Geometry.Vector3d(0,0,1)
Pl = rh.Geometry.Plane(P,vec)
# get dimstyle and change settings
ds = rh.DocObjects.DimensionStyle()
# change text properties ( a lot of options )
ds.Font = rh.DocObjects.Font(F)
ds.TextHeight = H
LL = [] #TextEntity_Width_Collumn
LLS = [] #TextEntity_Collumn
BB = [] #TextEntity_BoundingBox_Column
BHeight = [] #TextEntity_Height_All
for i in range(0,T.BranchCount):
B = [] # TextEntity_BoundingBox
BB.append(B)
L = [] # TextEntity_Width
LL.append(L)
LS = [] # TextEntity
LLS.append(LS)
for j in T.Branch(i):
Te = rh.Geometry.TextEntity
te = Te.Create(j,Pl,ds,False,0,0)
LS.append(te)
L.append(te.TextModelWidth)
Bounding_Box = te.GetBoundingBox(True)
B.append(Bounding_Box)
BHeight.append(abs(Bounding_Box.Min.Y-Bounding_Box.Max.Y))
# Get TextEntity_BoundingBox_with max width and inflate them with max height
LB = [] # TextEntity_BoundingBox with max width and height inflated
for e,i in enumerate(LL):
ind = i.index(max(i)) #index with max Textentity_BoundingBox_Width
BB_Max_W_H = BB[e][ind]
Max_Width_Height = abs(abs(BB_Max_W_H.Min.Y-BB_Max_W_H.Max.Y)-max(BHeight))/2
Width = abs(BB_Max_W_H.Min.X-BB_Max_W_H.Max.X)
BB_Max_W_H.Inflate(0,Max_Width_Height,0)
LB.append(BB_Max_W_H)
# inflate TransB
for i in LB:
widthB = abs(i.Min.X-i.Max.X)
i.Inflate(widthB*0.05,0,0)
tr = rh.Geometry.Transform.Translation(widthB*0.05,0,0)
i.Transform(tr)
FirstP = LB[0].GetCorners()[1]
counter = 0
TransB = []
Transf = []
TransB.append(LB[0])
def TransBox(FirstP,counter):
if counter < len(LB)-1:
counter = counter + 1
Vec = rh.Geometry.Vector3d(0,0,1)
PlaneTo = rh.Geometry.Plane(FirstP,Vec)
B = LB[counter]
PlaneFrom = rh.Geometry.Plane(B.Min,Vec)
Trans = rh.Geometry.Transform.PlaneToPlane(PlaneFrom,PlaneTo)
bbtr = Trans.TransformBoundingBox(LB[counter])
NextP = bbtr.GetCorners()[1]
TransB.append(bbtr)
Transf.append(Trans)
return TransBox(NextP,counter)
else:
return False
TransBox(FirstP,counter)
# get longest BranchList
ListLenght = []
for i in range(0,T.BranchCount):
ListLenght.append(len(T.Branch(i)))
# Create Transform for Bounding_Box_Grid
BBox_Height = rh.Geometry.Transform.Translation(0,TransB[0].Min.Y-TransB[0].Max.Y,0)
count = 0
TransBB = []
TransBB.append(BBox_Height)
def TransB_to_grid(BBox_Height,TransBB,count):
if count < max(ListLenght)-2:
count = count + 1
TransBB.append(TransBB[-1]*BBox_Height)
return TransB_to_grid(BBox_Height,TransBB,count)
else:
return False
TransB_to_grid(BBox_Height,TransBB,count)
# Create Bounding_Box_Grid
B_Grid = []
for i in TransB:
Grid = []
Grid.append(i)
B_Grid.append(Grid)
for j in TransBB:
Grid.append(j.TransformBoundingBox(i))
# Create Union BoundingBox from BoundingBoxGrid
UB_Grid = rh.Geometry.BoundingBox.Unset
for i in B_Grid:
for j in i:
UB_Grid.Union(j)
# Move TextEntity to BoundingBoxGrid
Vec = rh.Geometry.Vector3d(0,0,1)
for e,i in enumerate(B_Grid):
for ee,ii in enumerate(i):
# Get transform TextEntityBoundingBox to gridBox
Planefrom = rh.Geometry.Plane(BB[e][ee].Min,Vec)
Planeto = rh.Geometry.Plane(ii.Min,Vec)
trans = rh.Geometry.Transform.PlaneToPlane(Planefrom,Planeto)
LLS[e][ee].Transform(trans,ds)
# left top corner
CLT = UB_Grid.GetCorners()[3]
LT = rh.Geometry.Transform.PlaneToPlane(rh.Geometry.Plane(CLT,Vec),Pl)
# left bottom corner
CLB = UB_Grid.GetCorners()[0]
LB = rh.Geometry.Transform.PlaneToPlane(rh.Geometry.Plane(CLB,Vec),Pl)
# right top corner
CRT = UB_Grid.GetCorners()[2]
RT = rh.Geometry.Transform.PlaneToPlane(rh.Geometry.Plane(CRT,Vec),Pl)
# right bottom corner
CRB = UB_Grid.GetCorners()[1]
RB = rh.Geometry.Transform.PlaneToPlane(rh.Geometry.Plane(CRB,Vec),Pl)
for e,i in enumerate(B_Grid):
for ee,ii in enumerate(i):
if C == 'LeftTop':
LLS[e][ee].Transform(LT,ds)
ii.Transform(LT)
elif C == C == 'LeftBottom':
LLS[e][ee].Transform(LB,ds)
ii.Transform(LB)
elif C == C == 'RightTop':
LLS[e][ee].Transform(RT,ds)
ii.Transform(RT)
elif C == C == 'RightBottom':
LLS[e][ee].Transform(RB,ds)
ii.Transform(RB)
# create TextEntity Surface
TextS = []
for e,i in enumerate(LLS):
TextSS = []
TextS.append(TextSS)
for j in i:
TextSS.append(j.CreateSurfaces(ds,0,0))
# BoundingBox_Grid to Rectangle Grid
Rect_Grid = []
for i in B_Grid:
Grid = []
Rect_Grid.append(Grid)
for j in i:
Grid.append(rh.Geometry.Rectangle3d(Pl,j.Min,j.Max))
L = []
L.append(LLS)
L.append(B_Grid)
# TextSurface and Rectangles into DataTrees
S = gh.treehelpers.list_to_tree(TextS)
G = gh.treehelpers.list_to_tree(Rect_Grid)
# textentity rectangle
#box = rh.Geometry.Rectangle3d(P,bb.Min,bb.Max)
# bake text with same settings like textentity to get rhinotext object
if Bake:
sc.doc = rh.RhinoDoc.ActiveDoc
for e,i in enumerate(LLS):
for ee,j in enumerate(i):
rh.RhinoDoc.ActiveDoc.Objects.AddText(j.Text,j.Plane,j.TextHeight,F,False,False)
rh.RhinoDoc.ActiveDoc.Objects.AddRectangle(Rect_Grid[e][ee])
sc.doc = ghdoc
#rh.Display.DisplayPipeline.DrawBox()
Hi @James_Parrott ,
Thank you for posting the codes itself. I already asked the author from this forum
but no reply from him yet.
Great. It’s good to check. Who owns the first file by the way?
To get a “preview” in Grasshopper, the things to be previewed just need to be sent to a global variable, and an output param of the same name added to the Python component. The component in the second file has output params called S
and G
, that’s all that’s needed for a “preview” (outputting objects into Grasshopper from GhPython).
The complicated part is the first script does everything to the Rhino document on the fly, with rhinoscriptsyntax targetting Rhino:
But the second uses Rhino Common and targets Grasshopper (ghdoc
) for most of it, only switching the context to Rhino.RhinoDoc.ActiveDoc
at the end if Bake
.
So it might not take long at all to make the basic refactor above, but more is needed to guarantee it will all work as wished, i.e. testing it. The results of each individual modifications to the Rhino document (every call to rs.Add
something and rs.Move
something) need to be checked that they both work and produce the same change in the different Grasshopper context, and then baked afterwards.
I am definitely able to do this. However from experience, adapting code to run in a different context to the only context it was originally written and tested for, can quickly get fiddly. It can be quicker to rewrite it entirely. So this might only take an hour at best, but at worst it could require two days.
Hi @James_Parrott ,
Sorry for bothering you with this one. I have little to no knowledege about python or other coding. It will be great and very helpful not only for me but to others also if you will be able to do it.
Regarding the first file, it is from this link from @Rickson if im not mistaken:
I had some time to check this scripts and I added Text Size
and Text Alignment
options to the DataGrid_test.gh definition.
DataGrid.gh (14.5 KB)
Will be good if the Python script have an option to output Text entities to be able to edit the text in Rhino.
Made some additional progress. Found a way to generate and bake Text entities using the Elefront components, however looks like there is a bug into the Define Text Object
component because the justification and font size do not override the default style at bake time. I can see on the viewport the justification and font size changes but at bake time will reset everything to the values inherited from the default Dimension Style
used.
DataGrid_Elefront.gh (24.6 KB)
Interesting. Seems to work in Rhino 8. I’ve got it fixed in Rhino 7, will push an update in the next few days when I wrap some other fixes as well.
This should be fixed in 5.1.9: