/src/addons/Utils/DataExchange/STEP.py

http://pythonocc.googlecode.com/ · Python · 353 lines · 227 code · 41 blank · 85 comment · 42 complexity · 2286c34879db53e5ea9eaad98578c468 MD5 · raw file

  1. #!/usr/bin/env python
  2. ##Copyright 2009-2011 Thomas Paviot (tpaviot@gmail.com)
  3. ##
  4. ##This file is part of pythonOCC.
  5. ##
  6. ##pythonOCC is free software: you can redistribute it and/or modify
  7. ##it under the terms of the GNU Lesser General Public License as published by
  8. ##the Free Software Foundation, either version 3 of the License, or
  9. ##(at your option) any later version.
  10. ##
  11. ##pythonOCC is distributed in the hope that it will be useful,
  12. ##but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ##GNU Lesser General Public License for more details.
  15. ##
  16. ##You should have received a copy of the GNU Lesser General Public License
  17. ##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>.
  18. import os, os.path
  19. from OCC.TopoDS import *
  20. from OCC.BRep import *
  21. from OCC.STEPControl import *
  22. from OCC.Interface import *
  23. from OCC.IFSelect import *
  24. from OCC.TColStd import *
  25. from OCC.XCAFApp import *
  26. from OCC.STEPCAFControl import *
  27. from OCC.TDocStd import *
  28. from OCC.TCollection import *
  29. from OCC.XCAFDoc import *
  30. from OCC.TDF import *
  31. #from OCC.TopoDS import *
  32. from OCC import XCAFApp, TDocStd, TCollection, XCAFDoc, BRepPrimAPI, Quantity, TopLoc, gp, TPrsStd, XCAFPrs
  33. from OCC.STEPCAFControl import *
  34. from OCC.XSControl import *
  35. from OCC.STEPControl import *
  36. from OCC.Quantity import *
  37. from OCC.Utils.Topology import Topo
  38. from OCC.TopAbs import *
  39. import os
  40. class STEPImporter(object):
  41. def __init__(self,filename=None):
  42. self._shapes = []
  43. self._nbs = 0
  44. self.set_filename(filename)
  45. def get_nbr_shapes(self):
  46. """ Return the number of shapes from the importer
  47. """
  48. return self._nbs
  49. def set_filename(self, filename):
  50. if not os.path.isfile(filename):
  51. print "STEPImporter initialization Error: file %s not found."%filename
  52. self._filename = None
  53. else:
  54. self._filename = filename
  55. def read_file(self):
  56. """
  57. Read the STEP file and stores the result in a _shapes list
  58. """
  59. if not self._filename:
  60. print "ReadFile Error: first set the filename."
  61. return False
  62. aReader = STEPControl_Reader()
  63. status = aReader.ReadFile(self._filename)
  64. if status==IFSelect_RetDone:
  65. failsonly = False
  66. aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity)
  67. nbr = aReader.NbRootsForTransfer()
  68. print "%i root(s)"%nbr
  69. aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity)
  70. for n in range(1,nbr+1):
  71. ok = aReader.TransferRoot(n)
  72. self.nbs = aReader.NbShapes()
  73. if self.nbs == 0:
  74. print "At least one shape in STEP cannot be transfered"
  75. elif (nbr==1 and self.nbs==1):
  76. aResShape = aReader.Shape(1)
  77. if aResShape.IsNull():
  78. print "At least one shape in STEP cannot be transferred"
  79. self._shapes.append(aResShape)
  80. else:
  81. for i in range(1,self.nbs+1):
  82. aShape = aReader.Shape(i)
  83. if aShape.IsNull():
  84. print "At least one shape in STEP cannot be transferred"
  85. else:
  86. self._shapes.append(aShape)
  87. #B.Add(compound,aShape)
  88. return True
  89. else:
  90. print "Error: can't read file %s"%self._filename
  91. return False
  92. return False
  93. def get_compound(self):
  94. """ Create and returns a compound from the _shapes list
  95. """
  96. # Create a compound
  97. compound = TopoDS_Compound()
  98. B = BRep_Builder()
  99. B.MakeCompound(compound)
  100. # Populate the compound
  101. for shape in self._shapes:
  102. B.Add(compound,shape)
  103. return compound
  104. def get_shapes(self):
  105. return self._shapes
  106. class STEPExporter(object):
  107. def __init__(self, filename, verbose=False, schema='AP214CD'):
  108. '''
  109. writing STEP files
  110. @param filename: the file to save to eg. myshape.step
  111. @param verbose: verbosity of the STEP exporter
  112. @param schema: which STEP schema to use, either AP214CD or AP203
  113. '''
  114. self._shapes = []
  115. self.verbose = verbose
  116. self._filename = filename
  117. self.stepWriter = STEPControl_Writer()
  118. if not schema in ['AP203','AP214CD']:
  119. raise AssertionError('The schema string argument must be either "AP203" or "AP214CD"')
  120. else:
  121. Interface_Static_SetCVal("write.step.schema", schema)
  122. def set_tolerance(self, tolerance=0.0001):
  123. self.stepWriter.SetTolerance(tolerance)
  124. def add_shape(self, aShape):
  125. # First check the shape
  126. if aShape.IsNull():
  127. raise Assertion("STEPExporter Error: the shape is NULL")
  128. else:
  129. self._shapes.append(aShape)
  130. def write_file(self):
  131. for shp in self._shapes:
  132. status = self.stepWriter.Transfer(shp, STEPControl_AsIs )
  133. if status == IFSelect_RetDone:
  134. status = self.stepWriter.Write(self._filename)
  135. else:
  136. return False
  137. if self.verbose:
  138. self.stepWriter.PrintStatsTransfer()
  139. if status == IFSelect_RetDone:
  140. print "STEP transfer successful."
  141. return True
  142. else:
  143. return False
  144. class STEPOCAF_Import(object):
  145. '''
  146. Imports STEP file that support layers & colors
  147. '''
  148. def __init__(self, filename, layer_name='layer-00'):
  149. self.filename = filename
  150. self._shapes = [] #an empty string
  151. def get_shapes(self):
  152. return self._shapes
  153. def read_file(self):
  154. h_doc = TDocStd.Handle_TDocStd_Document()
  155. #print "Empty Doc?", h_doc.IsNull()
  156. # Create the application
  157. app = XCAFApp.GetApplication().GetObject()
  158. app.NewDocument(TCollection.TCollection_ExtendedString("MDTV-CAF"),h_doc)
  159. # Get root assembly
  160. doc = h_doc.GetObject()
  161. h_shape_tool = XCAFDoc.XCAFDoc_DocumentTool_shapetool(doc.Main())
  162. l_Colors = XCAFDoc.XCAFDoc_DocumentTool_colortool(doc.Main())
  163. l_Layers = XCAFDoc.XCAFDoc_DocumentTool_layertool(doc.Main())
  164. l_materials = XCAFDoc.XCAFDoc_DocumentTool_materialtool(doc.Main())
  165. STEPReader = STEPCAFControl_Reader()
  166. STEPReader.SetColorMode(True)
  167. STEPReader.SetLayerMode(True)
  168. STEPReader.SetNameMode(True)
  169. STEPReader.SetMatMode(True)
  170. status = STEPReader.ReadFile(str(self.filename))
  171. if status == IFSelect_RetDone:
  172. STEPReader.Transfer(doc.GetHandle())
  173. Labels = TDF_LabelSequence()
  174. ColorLabels = TDF_LabelSequence()
  175. #TopoDS_Shape aShape;
  176. shape_tool = h_shape_tool.GetObject()
  177. h_shape_tool.GetObject().GetFreeShapes(Labels)
  178. print 'Number of shapes at root :%i'%Labels.Length()
  179. for i in range(Labels.Length()):
  180. sub_shapes_labels = TDF_LabelSequence()
  181. print "Is Assembly?",shape_tool.isassembly(Labels.Value(i+1))
  182. sub_shapes = shape_tool.getsubshapes(Labels.Value(i+1),sub_shapes_labels)
  183. print 'Number of subshapes in the assemly :%i'%sub_shapes_labels.Length()
  184. l_Colors.GetObject().GetColors(ColorLabels)
  185. print 'Number of colors=%i'%ColorLabels.Length()
  186. #if(CL_Len>0):
  187. # ColorTool->GetColor(ColorLabels.Value(1),DefaultColor);
  188. for i in range(Labels.Length()):
  189. #print i
  190. print Labels.Value(i+1)
  191. aShape = h_shape_tool.GetObject().getshape(Labels.Value(i+1))
  192. m = l_Layers.GetObject().GetLayers(aShape)
  193. print dir(h_shape_tool.GetObject())
  194. #print c
  195. print "Lenght of popo :%i"%m.GetObject().Length()
  196. #v = m.GetObject().Value(0)#Value()
  197. #print v,v.Length()
  198. #for i in v.Length():
  199. # print chr(v.Value(i+1))
  200. #layer_labels = TDF_LabelSequence()
  201. #popo = Handle_TColStd_HSequenceOfExtendedString()
  202. #print 'Number of layers :%i'%layer_labels.Length()
  203. #print aShape,aShape.ShapeType()
  204. if aShape.ShapeType() == TopAbs_COMPOUND:
  205. t = Topo(aShape)
  206. for t in t.solids():
  207. self._shapes.append(t)
  208. return True
  209. class StepOCAF_Export(object):
  210. '''
  211. STEP export that support layers & colors
  212. '''
  213. def __init__(self, filename, layer_name='layer-00'):
  214. self.filename = filename
  215. self.h_doc = h_doc = TDocStd.Handle_TDocStd_Document()
  216. print "Empty Doc?", h_doc.IsNull()
  217. # Create the application
  218. app = XCAFApp.GetApplication().GetObject()
  219. app.NewDocument(TCollection.TCollection_ExtendedString("MDTV-CAF"),h_doc)
  220. # Get root assembly
  221. doc = h_doc.GetObject()
  222. h_shape_tool = XCAFDoc.XCAFDoc_DocumentTool().ShapeTool(doc.Main())
  223. l_Colors = XCAFDoc.XCAFDoc_DocumentTool().ColorTool(doc.Main())
  224. l_Layers = XCAFDoc.XCAFDoc_DocumentTool().LayerTool(doc.Main())
  225. labels = TDF_LabelSequence()
  226. ColorLabels = TDF_LabelSequence()
  227. #TopoDS_Shape aShape;
  228. self.shape_tool = h_shape_tool.GetObject()
  229. self.top_label = self.shape_tool.NewShape()
  230. self.colors = l_Colors.GetObject()
  231. self.layers = l_Layers.GetObject()
  232. self.current_color = Quantity.Quantity_Color(Quantity.Quantity_NOC_RED)
  233. self.current_layer = self.layers.AddLayer(TCollection_ExtendedString(layer_name))
  234. self.layer_names = {}
  235. def set_color(self, r=1,g=1,b=1, color=None):
  236. if not color is None:
  237. self.current_color = color
  238. else:
  239. clr = Quantity.Quantity_Color(r,g,b,0)
  240. self.current_color = clr
  241. def set_layer(self, layer_name):
  242. '''set the current layer name
  243. if the layer has already been set before, that TDF_Label will be used
  244. @param layer_name: string that is the name of the layer
  245. '''
  246. if layer_name in self.layer_names:
  247. self.current_layer = self.layer_names[layer_name]
  248. else:
  249. self.current_layer = self.layers.AddLayer(TCollection_ExtendedString(layer_name))
  250. self.layer_names[layer_name] = self.current_layer
  251. def add_shape(self, shape, color=None, layer=None):
  252. '''add a shape to export
  253. a layer and color can be specified.
  254. note that the set colors / layers will be used for further objects
  255. added too!
  256. @param shape: the TopoDS_Shape to export
  257. @param color: can be a tuple: (r,g,b) or a Quantity_Color instance
  258. @param layer: string with the layer name
  259. '''
  260. assert issubclass(shape.__class__, TopoDS_Shape) or isinstance(shape, TopoDS_Shape), 'not a TopoDS_Shape or subclass'
  261. shp_label = self.shape_tool.AddShape( shape )
  262. if color is None:
  263. self.colors.SetColor(shp_label, self.current_color, XCAFDoc.XCAFDoc_ColorGen)
  264. else:
  265. if isinstance(color, Quantity_Color):
  266. self.current_color = color
  267. else:
  268. assert len(color) == 3, 'expected a tuple with three values < 1.'
  269. r,g,b = color
  270. self.set_color(r,g,b)
  271. self.colors.SetColor(shp_label, self.current_color, XCAFDoc.XCAFDoc_ColorGen)
  272. if layer is None:
  273. self.layers.SetLayer(shp_label, self.current_layer)
  274. else:
  275. self.set_layer(layer)
  276. self.layers.SetLayer(shp_label, self.current_layer)
  277. def write_file(self):
  278. WS = XSControl_WorkSession()
  279. writer = STEPCAFControl_Writer( WS.GetHandle(), False )
  280. writer.Transfer(self.h_doc, STEPControl_AsIs)
  281. print 'writing STEP file'
  282. status = writer.Write(self.filename)
  283. print 'status:', status
  284. def TestImport():
  285. """
  286. Imports a STEP file.
  287. """
  288. myImporter = STEPImporter("box_203.stp")
  289. myImporter.read_file()
  290. print myImporter.get_shapes()
  291. def TestExport():
  292. """
  293. Exports a TopoDS_Shape to a STEP file.
  294. """
  295. from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox
  296. test_shape = BRepPrimAPI_MakeBox(100.,100.,100.).Shape()
  297. # export to AP203 schema
  298. AP203_Exporter = STEPExporter('box_203.stp',schema='AP203')
  299. AP203_Exporter.add_shape(test_shape)
  300. AP203_Exporter.write_file()
  301. # export AP214 schema
  302. AP214CD_Exporter = STEPExporter('box_214CD.stp',schema='AP214CD')
  303. AP214CD_Exporter.add_shape(test_shape)
  304. AP214CD_Exporter.write_file()
  305. if __name__=='__main__':
  306. TestExport()
  307. TestImport()