1 // Copyright (C) 2014-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <GeomAlgoAPI_STEPImportXCAF.h>
22 #include <BRep_Builder.hxx>
24 #include <Interface_EntityIterator.hxx>
25 #include <Interface_Graph.hxx>
26 #include <Interface_InterfaceModel.hxx>
28 #include <Quantity_Color.hxx>
30 #include <StepRepr_DescriptiveRepresentationItem.hxx>
31 #include <StepRepr_ProductDefinitionShape.hxx>
32 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
33 #include <StepRepr_Representation.hxx>
35 #include <TDataStd_Name.hxx>
36 #include <TDF_ChildIDIterator.hxx>
37 #include <TDocStd_Document.hxx>
39 #include <TopExp_Explorer.hxx>
41 #include <Transfer_TransientProcess.hxx>
42 #include <TransferBRep.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
45 #include <XCAFApp_Application.hxx>
46 #include <XCAFDoc_DocumentTool.hxx>
47 #include <XCAFDoc_Location.hxx>
48 #include <XCAFDoc_ShapeTool.hxx>
49 #include <XSControl_TransferReader.hxx>
50 #include <XSControl_WorkSession.hxx>
51 #include <XCAFDoc_ColorTool.hxx>
52 #include <XCAFDoc_MaterialTool.hxx>
54 #include <Locale_Convert.h>
57 std::shared_ptr<GeomAPI_Shape> setGeom(const Handle(XCAFDoc_ShapeTool) &shapeTool,
58 const TDF_Label &theLabel,
59 std::string& theError);
61 /// read attributs for label
62 void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &theShapeTool,
63 const Handle(XCAFDoc_ColorTool) &theColorTool,
64 const Handle(XCAFDoc_MaterialTool) &TheMaterialTool,
65 const TDF_Label &theLabel,
66 const TopLoc_Location &theLoc,
67 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
68 std::map< std::wstring, std::list<std::wstring>> &theMaterialShape,
71 // store Materiel for theShapeLabel in the map theMaterialShape
72 void storeMaterial(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
73 const Handle(Standard_Transient) &theEnti,
74 const TopTools_IndexedMapOfShape &theIndices,
75 const Handle(Transfer_TransientProcess) &theTP,
76 const TDF_Label &theShapeLabel,
77 std::map< std::wstring, std::list<std::wstring>> &theMaterialShape);
79 //=============================================================================
80 TopoDS_Shape getShape(const Handle(Standard_Transient) &theEnti,
81 const Handle(Transfer_TransientProcess) &theTP)
84 Handle(Transfer_Binder) aBinder = theTP->Find(theEnti);
86 if (aBinder.IsNull()) {
90 aResult = TransferBRep::ShapeResult(aBinder);
95 //=============================================================================
96 std::shared_ptr<GeomAPI_Shape> readAttributes(STEPCAFControl_Reader &theReader,
97 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
98 const bool theIsMaterials,
99 std::map< std::wstring,std::list<std::wstring>> &theMaterialShape,
100 std::string& theError)
102 // dummy XCAF Application to handle the STEP XCAF Document
103 Handle(XCAFApp_Application) dummy_app = XCAFApp_Application::GetApplication();
104 // XCAF Document to contain the STEP/IGES file itself
105 Handle(TDocStd_Document) adoc;
107 dummy_app->NewDocument( TCollection_ExtendedString("MDTV-CAF"), adoc);
108 // transfer STEP/IGES into the document, and get the main label
109 theReader.Transfer(adoc);
110 TDF_Label mainLabel = adoc->Main();
111 Handle_XCAFDoc_ShapeTool shapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel);
112 Handle_XCAFDoc_ColorTool colorTool = XCAFDoc_DocumentTool::ColorTool(mainLabel);
113 Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_DocumentTool::MaterialTool(mainLabel);
114 // traverse the labels recursively to set attributes on shapes
115 setShapeAttributes(shapeTool, colorTool, materialTool, mainLabel,
116 TopLoc_Location(),theResultBody,theMaterialShape,false);
118 std::shared_ptr<GeomAPI_Shape> ageom = setGeom(shapeTool,mainLabel,theError);
120 STEPControl_Reader aReader = theReader.ChangeReader();
122 // BEGIN: reading materials of sub-shapes from file
123 if (theIsMaterials) {
124 TopTools_IndexedMapOfShape anIndices;
125 TopExp::MapShapes(ageom->impl<TopoDS_Shape>(), anIndices);
127 Handle(Interface_InterfaceModel) Model = aReader.WS()->Model();
128 Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader();
130 Handle(Transfer_TransientProcess) TP = TR->TransientProcess();
132 Standard_Integer nb = Model->NbEntities();
134 for (Standard_Integer ie = 1; ie <= nb; ie++) {
135 Handle(Standard_Transient) enti = Model->Value(ie);
138 storeMaterial(theResultBody,enti, anIndices, TP, mainLabel,theMaterialShape);
142 if (adoc->CanClose() == CDM_CCS_OK)
147 //=============================================================================
148 std::shared_ptr<GeomAPI_Shape> setGeom(const Handle(XCAFDoc_ShapeTool) &theShapeTool,
149 const TDF_Label& /*theLabel*/,
150 std::string& theError)
153 TopoDS_Compound aCompound;
154 aB.MakeCompound(aCompound);
156 TDF_LabelSequence aFrshapes;
157 theShapeTool->GetShapes(aFrshapes);
159 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
161 if (aFrshapes.Length() == 0) {
162 aGeomShape->setImpl(new TopoDS_Shape());
164 } else if (aFrshapes.Length() == 1) {
165 TopoDS_Shape shape = theShapeTool->GetShape(aFrshapes.Value(1));
166 aGeomShape->setImpl(new TopoDS_Shape(shape));
169 for (Standard_Integer i=1; i<=aFrshapes.Length(); i++) {
170 TopoDS_Shape aS = theShapeTool->GetShape(aFrshapes.Value(i));
171 TDF_Label aLabel = theShapeTool->FindShape(aS, Standard_False);
172 if ( (!aLabel.IsNull()) && (theShapeTool->IsShape(aLabel)) ) {
173 if (theShapeTool->IsFree(aLabel) ) {
177 if (aS.ShapeType() != TopAbs_SOLID && !theShapeTool->IsReference(aLabel)){
178 for(TDF_ChildIterator anIt(aLabel); anIt.More(); anIt.Next()) {
179 aB.Add(aCompound, theShapeTool->GetShape(anIt.Value()) );
182 aB.Add(aCompound, aS);
189 TopoDS_Shape aShape = aCompound;
190 // Check if any BRep entity has been read, there must be at least a vertex
191 if (!TopExp_Explorer( aShape, TopAbs_VERTEX ).More()) {
192 theError = "No geometrical data in the imported file.";
193 aGeomShape->setImpl(new TopoDS_Shape());
197 aGeomShape->setImpl(new TopoDS_Shape(aShape));
201 //=============================================================================
202 void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &theShapeTool,
203 const Handle(XCAFDoc_ColorTool) &theColorTool,
204 const Handle(XCAFDoc_MaterialTool) &theMaterialTool,
205 const TDF_Label &theLabel,
206 const TopLoc_Location &theLoc,
207 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
208 std::map< std::wstring,std::list<std::wstring>> &theMaterialShape,
211 std::wstring aShapeName;
212 Handle(TDataStd_Name) aN;
214 if (theLabel.FindAttribute(TDataStd_Name::GetID(), aN)) {
215 TCollection_ExtendedString aName = aN->Get();
217 aShapeName = Locale::Convert::toWString(TCollection_AsciiString(aName).ToCString()) ;
220 TopLoc_Location aPartLoc = theLoc;
221 Handle(XCAFDoc_Location) al;
222 if (theLabel.FindAttribute(XCAFDoc_Location::GetID(), al)) {
224 aPartLoc = aPartLoc * al->Get();
226 aPartLoc = al->Get();
230 if (theShapeTool->IsReference(theLabel) && theShapeTool->GetReferredShape(theLabel, aRef)) {
232 setShapeAttributes( theShapeTool, theColorTool, theMaterialTool, aRef,
233 aPartLoc,theResultBody,theMaterialShape,true);
236 if (theShapeTool->IsSimpleShape(theLabel) && (theIsRef || theShapeTool->IsFree(theLabel))) {
238 TopoDS_Shape aShape = theShapeTool->GetShape(theLabel);
240 std::shared_ptr<GeomAPI_Shape> aShapeGeom(new GeomAPI_Shape);
241 if (!theLoc.IsIdentity()) {
244 aShapeGeom->setImpl(new TopoDS_Shape(aShape));
245 aShapeName = theResultBody->addShapeName(aShapeGeom, aShapeName);
248 aShape.Location(theIsRef ? theLoc : aPartLoc);
250 (aShape.ShapeType() == TopAbs_VERTEX) ?
252 (aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) ?
254 (aShape.ShapeType() == TopAbs_FACE ||
255 aShape.ShapeType() == TopAbs_SHELL) ? 2 :3;
257 Handle(TCollection_HAsciiString) aMatName;
258 Handle(TCollection_HAsciiString) aMatDescription;
259 Standard_Real aMatDensity;
260 Handle(TCollection_HAsciiString) aMatDensName;
261 Handle(TCollection_HAsciiString) aMatDensValType;
263 if (theMaterialTool->GetMaterial(theLabel, aMatName, aMatDescription, aMatDensity,
264 aMatDensName, aMatDensValType)) {
265 std::wstring aNameMaterial = Locale::Convert::toWString(aMatName->ToCString());
267 theMaterialShape[aNameMaterial].push_back(aShapeName);
271 if (theColorTool->GetColor(theLabel, XCAFDoc_ColorGen, aCol)) {
272 double r = aCol.Red(), g = aCol.Green(), b = aCol.Blue();
273 std::vector<int> ColRGB = {int(r*255),int(g*255),int(b*255)};
274 theResultBody->addShapeColor(aShapeName, ColRGB);
275 } else if (theColorTool->GetColor(theLabel, XCAFDoc_ColorSurf, aCol)) {
276 double r = aCol.Red(), g = aCol.Green(), b = aCol.Blue();
277 std::vector<int> aColRGB = {int(r*255),int(g*255),int(b*255)};
278 theResultBody->addShapeColor(aShapeName, aColRGB);
279 } else if (theColorTool->GetColor(theLabel, XCAFDoc_ColorCurv, aCol)) {
280 double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue();
281 std::vector<int> aColRGB = {int(aR*255),int(aG*255),int(aB*255)};
282 theResultBody->addShapeColor(aShapeName, aColRGB);
284 // check explicit coloring of boundary entities
286 TopExp_Explorer aXp2(aShape, TopAbs_FACE);
287 while (aXp2.More()) {
288 if (theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorGen, aCol) ||
289 theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorSurf, aCol) ||
290 theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorCurv, aCol)) {
291 double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue();
292 TopoDS_Face aFace = TopoDS::Face(aXp2.Current());
293 std::vector<int> aColRGB = {int(aR*255),int(aG*255),int(aB*255)};
294 std::wstringstream aNameFace;
295 TopoDS_Shape aShapeface = aXp2.Current();
296 if (!theLoc.IsIdentity()){
297 aShapeface.Move(theLoc);
299 aShapeGeom->setImpl(new TopoDS_Shape(aShapeface));
300 theResultBody->addShapeColor(
301 theResultBody->addShapeName(aShapeGeom , aNameFace.str()), aColRGB);
307 if (!theShapeTool->IsReference(theLabel) ){
308 TopoDS_Shape aShape = theShapeTool->GetShape(theLabel);
310 std::shared_ptr<GeomAPI_Shape> aShapeGeom(new GeomAPI_Shape);
311 if (!theLoc.IsIdentity()){
314 aShapeGeom->setImpl(new TopoDS_Shape(aShape));
315 aShapeName = theResultBody->addShapeName(aShapeGeom, aShapeName);
317 for(TDF_ChildIterator anIt(theLabel); anIt.More(); anIt.Next()) {
319 setShapeAttributes( theShapeTool, theColorTool, theMaterialTool,
320 anIt.Value(), aPartLoc,theResultBody,theMaterialShape, theIsRef);
325 //=============================================================================
326 void storeMaterial( std::shared_ptr<ModelAPI_ResultBody> theResultBody,
327 const Handle(Standard_Transient) &theEnti,
328 const TopTools_IndexedMapOfShape &theIndices,
329 const Handle(Transfer_TransientProcess) &theTP,
330 const TDF_Label &/*theShapeLabel*/,
331 std::map< std::wstring, std::list<std::wstring>> &theMaterialShape )
333 // Treat Product Definition Shape only.
334 Handle(StepRepr_ProductDefinitionShape) aPDS =
335 Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti);
336 Handle(StepBasic_ProductDefinition) aProdDef;
338 if (!aPDS.IsNull()) {
339 // Product Definition Shape ==> Product Definition
340 aProdDef = aPDS->Definition().ProductDefinition();
343 if (!aProdDef.IsNull()) {
344 // Product Definition ==> Property Definition
345 const Interface_Graph &aGraph = theTP->Graph();
346 Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef);
349 for(aSubs.Start(); aSubs.More(); aSubs.Next()) {
350 Handle(StepRepr_PropertyDefinition) aPropD =
351 Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value());
353 if (!aPropD.IsNull()) {
354 // Property Definition ==> Representation.
355 Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD);
357 for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) {
358 Handle(StepRepr_PropertyDefinitionRepresentation) aPDR =
359 Handle(StepRepr_PropertyDefinitionRepresentation)::
360 DownCast(aSubs1.Value());
362 if (!aPDR.IsNull()) {
363 // Property Definition ==> Material Name.
364 Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation();
366 if (!aRepr.IsNull()) {
367 Standard_Integer anIr;
369 for(anIr = 1; anIr <= aRepr->NbItems(); anIr++) {
370 Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(anIr);
371 Handle(StepRepr_DescriptiveRepresentationItem) aDRI =
372 Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI);
374 if (!aDRI.IsNull()) {
375 // Get shape from Product Definition
376 Handle(TCollection_HAsciiString) aMatName = aDRI->Name();
377 if (!aMatName.IsNull()) {
378 TCollection_ExtendedString
379 aMatNameExt (aMatName->ToCString());
381 if (aShape.IsNull()) {
383 aShape = getShape(aProdDef, theTP);
384 if (aShape.IsNull()) {
389 // as PRODUCT can be included in the main shape
390 // several times, we look here for all iclusions.
391 Standard_Integer anISub, aNbSubs = theIndices.Extent();
393 for (anISub = 1; anISub <= aNbSubs; anISub++) {
394 TopoDS_Shape aSub = theIndices.FindKey(anISub);
396 if (aSub.IsPartner(aShape)) {
397 std::shared_ptr<GeomAPI_Shape> aShapeGeom(new GeomAPI_Shape);
398 aShapeGeom->setImpl(new TopoDS_Shape(aSub));
399 std::wstring aNom = theResultBody->findShapeName(aShapeGeom);
400 std::wstring aMName= Locale::Convert::toWString(aMatName->ToCString());
401 theMaterialShape[aMName].push_back(aNom);