In order to export a file with information other than just points, you cannot export directly from Rhino using the Export command. You will have to specifically write a text file with Python functions. This is not that complicated, but does require some understanding of how Python reads and writes text files - the Python documentation website input/output section is a good place to start. I will post some sample code in a bit. --Mitch
Hello
I succedeed to write the info on a file, name id , layer…
now i am tring to get the result of my area centroid result
How i can the result back into python code
thank you
import rhinoscriptsyntax as rs
pts = rs.GetObject("Select Object for AreaCentroid")
rs.Command("AreaCentroid")
rs.Command("Enter")
Something like the following should work… I used semicolons as separators since there are points in there separated by commas. There are a few subtleties in the script such as the line formatting code and what to do if the object does not have a name or one or more of the properties asked for…
import rhinoscriptsyntax as rs
def TestExportObjectData():
msg="Select surface/polysurface objects to export data"
objs = rs.GetObjects(msg,8+16,preselect=True)
if not objs: return
filter = "CSV File (*.csv)|*.csv||"
filename = rs.SaveFileName("Save data file as", filter)
if not filename: return
file = open(filename, "w")
for obj in objs:
ID=str(obj)
name=rs.ObjectName(obj)
area=rs.SurfaceArea(obj)
vol=rs.SurfaceVolume(obj)
acent=rs.SurfaceAreaCentroid(obj)
vcent=rs.SurfaceVolumeCentroid(obj)
if area:aa=area[0]
else: aa=""
if vol: vv=vol[0]
else: vv=""
if acent:ac=acent[0]
else: ac=""
if vcent: vc=vcent[0]
else: vc=""
file.write("{};{};{};{};{};{}\n".format(ID,name,aa,vv,ac,vc))
file.close()
TestExportObjectData()
If you are opening the file directly in Excel, it probably won’t work well. What you need to do is open a blank Excel file and then use Data>import from text. Then choose semicolon as separator. That gives me the following:
You have ID, name, area, volume area centroid, volume centroid in separate columns. The points (last two columns) are in one cell separated by commas. This could also be changed.
I have tried to modify a bit the code for Cumulative Area Centroid
Exemple
i have a design with
9 polysurfaces into 52 surfaces.
With rhino
Cumulative Area Centroid = 1290.75092,11143.9093,-40.5104309 (+/- 1e-06,1e-05,1e-08) for 53 surfaces
With the program a success to have the Area Centroid og the 9 polysurfaces (So 9 line of result)
but not all the Cumulative Area Centroid like i have with rhrino
I have tried to join then but canot join more than 9 polysurfaces into 52 surfaces.
I have tried to group them to make one object but no sucess
also tried to make a block
If I’m not mistaken, the cumulative area (or volume) centroid is just the average of all the individual ones. So you just need to store all your centroid points in a list and then average them at the end (add them all and divide by the number of points).
import rhinoscriptsyntax as rs
msg="Select surface/polysurface objects for average centroid"
objs = rs.GetObjects(msg,8+16,preselect=True)
aPts=[]
vPts=[]
for obj in objs:
ac=rs.SurfaceAreaCentroid(obj)
vc=rs.SurfaceVolumeCentroid(obj)
aPts.append(ac[0])
vPts.append(vc[0])
#the following line averages a list of points and returns the result
avgAreaPt=reduce(lambda x, y: x+y, aPts)/len(aPts)
avgVolPt=reduce(lambda x, y: x+y, vPts)/len(vPts)
rs.AddPoints([avgAreaPt,avgVolPt])
The following is the “longhand” way to average points:
#aPts is your list of points to average
#start with a point at 0,0,0
addPts=rs.coerce3dpoint([0,0,0])
#add all the points successively
for pt in aPts: addPts+=pt
#divide by the number of points
avgAreaPt=addPts/len(aPts)
I am wondering
Why rhrino is able to make the area and surface area of a circle line
and the command python “‘SurfaceAreaCentroid’” is not working with a circle line
I really thought when i start to get the same result, or just gey the result of the command line
import rhinoscriptsyntax as rs
objs = rs.GetObjects()
aPts=[]
for obj in objs:
ac=rs.SurfaceAreaCentroid(obj)
aPts.append(ac[0])
avgAreaPt=reduce(lambda x, y: x+y, aPts)/len(aPts)
rs.AddPoints([avgAreaPt])
addPts=rs.coerce3dpoint([0,0,0])
#add all the points successively
for pt in aPts: addPts+=pt
#divide by the number of points
avgAreaPt=addPts/len(aPts)
print "avgAreaPt:", avgAreaPt
Message: ‘NoneType’ object is unsubscriptable with the circle line
For curves, you would need to use CurveAreaCentroid() and not SurfaceAreaCentroid(). Rhinoscriptsyntax methods are lower-level operations than normal Rhino commands, and do not have all the same functionality. So often you need to filter for object type and combine several methods.
Hello Helvetosaur,
thank you for information and the scripts above - very helpfull!
An addition to the surface object informations, meaning saving the information of different lengths of curves besides their id and names in the same document, I haven´t been able to achieve.
Admitting of not being very talented in scripting yet I tried a sort of copy and paste solution without success:
def TestExportObjectData():
lenght=0.0
msg="Select objects to export data"
objs = rs.GetObjects(msg,4+8+16,preselect=True)
if not objs: return
filter = "CSV File (*.csv)|*.csv||"
filename = rs.SaveFileName("Save data file as", filter)
if not filename: return
file = open(filename, "w")
for obj in objs:
if rs.IsCurve(obj):
length=rs.CurveLength(obj)
ID=str(obj)
name=rs.ObjectName(obj)
area=rs.SurfaceArea(obj)
vol=rs.SurfaceVolume(obj)
acent=rs.SurfaceAreaCentroid(obj)
vcent=rs.SurfaceVolumeCentroid(obj)
if area:aa=area[0]
else: aa=""
if vol: vv=vol[0]
else: vv=""
if acent:ac=acent[0]
else: ac=""
if vcent: vc=vcent[0]
else: vc=""
if length: lg=length[0]
else: lg=""
file.write("{};{};{};{};{};{};{}\n".format(ID,name,aa,vv,ac,vc,lg))
file.close()
TestExportObjectData()
Apparently i need to handle objects containing surfaces and objects containing curves differently, but how:
import rhinoscriptsyntax as rs
global length
def TestExportCurveLength():
# Get the curve objects
msg="Select surface/curve objects to export data"
arrObjects = rs.GetObjects(msg,rs.filter.curve, True, True)
if( arrObjects==None ): return
rs.UnselectObjects(arrObjects)
filter = "CSV File (*.csv)|*.csv||"
filename = rs.SaveFileName("Save data file as", filter)
if not filename: return
length = 0.0
count = 0
for object in arrObjects:
if rs.IsCurve(object):
#Get the curve length
length = rs.CurveLength(object)
count += 1
if (count>0):
file = open(filename, "w")
for object in arrObjects:
ID=str(object)
name=rs.ObjectName(object)
area=rs.SurfaceArea(object)
if length: lg=length[0]
else: lg=""
file.write("{};{};{}\n".format(ID,name,lg))
file.close()
TestExportCurveLength()