1 // Created on: 2000-08-17
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <IGESCAFControl.hxx>
17 #include <IGESCAFControl_Writer.hxx>
18 #include <IGESData_IGESEntity.hxx>
19 #include <IGESData_IGESModel.hxx>
20 #include <IGESData_NameEntity.hxx>
21 #include <IGESGraph_Color.hxx>
22 #include <IGESGraph_DefinitionLevel.hxx>
23 #include <IGESSolid_Face.hxx>
24 #include <IGESBasic_Name.hxx>
25 #include <NCollection_DataMap.hxx>
26 #include <Standard_Transient.hxx>
27 #include <TCollection_AsciiString.hxx>
28 #include <TCollection_HAsciiString.hxx>
29 #include <TCollection_HExtendedString.hxx>
30 #include <TColStd_HSequenceOfExtendedString.hxx>
31 #include <TDataStd_Name.hxx>
32 #include <TDF_ChildIterator.hxx>
33 #include <TDF_Label.hxx>
34 #include <TDF_LabelSequence.hxx>
35 #include <TDocStd_Document.hxx>
37 #include <TopExp_Explorer.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Iterator.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopTools_SequenceOfShape.hxx>
43 #include <Transfer_FinderProcess.hxx>
44 #include <Transfer_TransientListBinder.hxx>
45 #include <TransferBRep.hxx>
46 #include <TransferBRep_ShapeMapper.hxx>
47 #include <XCAFDoc_ColorTool.hxx>
48 #include <XCAFDoc_DocumentTool.hxx>
49 #include <XCAFDoc_LayerTool.hxx>
50 #include <XCAFDoc_ShapeTool.hxx>
51 #include <XCAFPrs.hxx>
52 #include <XCAFPrs_Style.hxx>
53 #include <XSControl_WorkSession.hxx>
57 typedef NCollection_DataMap<TopoDS_Shape, TCollection_ExtendedString> DataMapOfShapeNames;
59 void CollectShapeNames (const TDF_Label& theLabel,
60 const TopLoc_Location& theLocation,
61 const Handle(TDataStd_Name)& thePrevName,
62 DataMapOfShapeNames& theMapOfShapeNames)
64 Standard_Boolean hasReferredShape = Standard_False;
65 Standard_Boolean hasComponents = Standard_False;
66 TDF_Label aReferredLabel;
68 Handle(TDataStd_Name) aName;
69 theLabel.FindAttribute (TDataStd_Name::GetID(), aName);
71 if ( XCAFDoc_ShapeTool::GetReferredShape ( theLabel, aReferredLabel ) )
73 TopLoc_Location aSubLocation = theLocation.Multiplied ( XCAFDoc_ShapeTool::GetLocation ( theLabel ) );
74 CollectShapeNames (aReferredLabel, aSubLocation, aName, theMapOfShapeNames);
75 hasReferredShape = Standard_True;
78 TDF_LabelSequence aSeq;
79 if (XCAFDoc_ShapeTool::GetComponents (theLabel, aSeq))
81 for (Standard_Integer anIter = 1; anIter <= aSeq.Length(); anIter++)
83 CollectShapeNames (aSeq.Value (anIter), theLocation, aName, theMapOfShapeNames );
85 hasComponents = Standard_True;
89 if (XCAFDoc_ShapeTool::GetSubShapes (theLabel, aSeq))
91 for (Standard_Integer anIter = 1; anIter <= aSeq.Length(); anIter++)
94 if (!XCAFDoc_ShapeTool::GetShape (aSeq.Value (anIter), aShape)) continue;
95 if (!aSeq.Value (anIter).FindAttribute (TDataStd_Name::GetID(), aName)) continue;
96 theMapOfShapeNames.Bind (aShape, aName->Get());
100 if (!hasReferredShape && !hasComponents)
103 if (!XCAFDoc_ShapeTool::GetShape (theLabel, aShape)) return;
104 aShape.Move (theLocation);
105 theMapOfShapeNames.Bind (aShape, thePrevName->Get());
110 //=======================================================================
111 //function : IGESCAFControl_Writer
113 //=======================================================================
115 IGESCAFControl_Writer::IGESCAFControl_Writer () :
116 myColorMode( Standard_True ),
117 myNameMode ( Standard_True ),
118 myLayerMode( Standard_True )
122 //=======================================================================
123 //function : IGESCAFControl_Writer
125 //=======================================================================
127 IGESCAFControl_Writer::IGESCAFControl_Writer (const Handle(XSControl_WorkSession)& WS,
128 const Standard_Boolean /*scratch*/ )
130 // this code does things in a wrong way, it should be vice-versa
131 WS->SetModel ( Model() );
132 WS->SetMapWriter ( TransferProcess() );
133 myColorMode = Standard_True;
134 myNameMode = Standard_True;
135 myLayerMode = Standard_True;
137 // SetWS (WS,scratch); // this should be the only required command here
140 //=======================================================================
141 //function : Transfer
143 //=======================================================================
145 Standard_Boolean IGESCAFControl_Writer::Transfer (const Handle(TDocStd_Document) &doc)
147 // translate free top-level shapes of the DECAF document
148 Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( doc->Main() );
149 if ( STool.IsNull() ) return Standard_False;
151 TDF_LabelSequence labels;
152 STool->GetFreeShapes ( labels );
153 return Transfer (labels);
156 //=======================================================================
157 //function : Transfer
159 //=======================================================================
161 Standard_Boolean IGESCAFControl_Writer::Transfer (const TDF_Label& label)
163 TDF_LabelSequence labels;
164 labels.Append( label );
165 return Transfer( labels );
168 //=======================================================================
169 //function : Transfer
171 //=======================================================================
173 Standard_Boolean IGESCAFControl_Writer::Transfer (const TDF_LabelSequence& labels)
175 if ( labels.Length() <=0 ) return Standard_False;
176 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
177 TopoDS_Shape shape = XCAFDoc_ShapeTool::GetShape ( labels.Value(i) );
178 if ( ! shape.IsNull() )
180 // IGESControl_Writer::Transfer ( shape );
184 if ( GetColorMode() )
185 WriteAttributes ( labels );
188 if ( GetLayerMode() )
189 WriteLayers ( labels );
193 WriteNames( labels );
196 // WS()->ComputeGraph ( Standard_True );
199 return Standard_True;
202 //=======================================================================
205 //=======================================================================
207 Standard_Boolean IGESCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
208 const Standard_CString filename)
210 if ( ! Transfer ( doc ) ) return Standard_False;
211 return Write ( filename ) == IFSelect_RetDone;
214 //=======================================================================
217 //=======================================================================
219 Standard_Boolean IGESCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
220 const TCollection_AsciiString &filename)
222 if ( ! Transfer ( doc ) ) return Standard_False;
223 return Write ( filename.ToCString() ) == IFSelect_RetDone;
226 //=======================================================================
227 //function : WriteAttributes
229 //=======================================================================
231 Standard_Boolean IGESCAFControl_Writer::WriteAttributes (const TDF_LabelSequence& labels)
234 if ( labels.Length() <=0 ) return Standard_False;
235 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
236 TDF_Label L = labels.Value(i);
238 // collect color settings
239 XCAFPrs_IndexedDataMapOfShapeStyle settings;
241 XCAFPrs::CollectStyleSettings ( L, loc, settings );
242 if ( settings.Extent() <=0 ) continue;
244 // get a target shape and try to find corresponding context
245 // (all the colors set under that label will be put into that context)
247 if ( ! XCAFDoc_ShapeTool::GetShape ( L, S ) ) continue;
249 // iterate on subshapes and create IGES styles
250 XCAFPrs_DataMapOfStyleTransient colors;
251 TopTools_MapOfShape Map;
252 const XCAFPrs_Style inherit;
253 MakeColors ( S, settings, colors, Map, inherit );
256 return Standard_True;
259 //=======================================================================
260 //function : MakeColors
262 //=======================================================================
264 void IGESCAFControl_Writer::MakeColors (const TopoDS_Shape &S,
265 const XCAFPrs_IndexedDataMapOfShapeStyle &settings,
266 XCAFPrs_DataMapOfStyleTransient &colors,
267 TopTools_MapOfShape &Map,
268 const XCAFPrs_Style &inherit)
270 // skip already processed shapes
271 if ( ! Map.Add ( S ) ) return;
273 // check if shape has its own style (or inherits from ancestor)
274 XCAFPrs_Style style = inherit;
275 if ( settings.Contains(S) ) {
276 XCAFPrs_Style own = settings.FindFromKey(S);
277 if ( own.IsSetColorCurv() ) style.SetColorCurv ( own.GetColorCurv() );
278 if ( own.IsSetColorSurf() ) style.SetColorSurf ( own.GetColorSurf() );
281 // analyze whether current entity should get a color
282 Standard_Boolean hasColor = Standard_False;
284 if ( S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SOLID) {
285 if ( style.IsSetColorSurf() ) {
286 hasColor = Standard_True;
287 col = style.GetColorSurf();
290 else if ( S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE ) {
291 if ( style.IsSetColorCurv() ) {
292 hasColor = Standard_True;
293 col = style.GetColorCurv();
297 // if color has to be assigned, try to do this
299 Handle(IGESGraph_Color) colent;
300 Standard_Integer rank = IGESCAFControl::EncodeColor ( col );
302 XCAFPrs_Style c; // style used as key in the map
303 c.SetColorSurf ( col );
304 if ( colors.IsBound ( c ) ) {
305 colent = Handle(IGESGraph_Color)::DownCast ( colors.Find(c) );
308 Handle(TCollection_HAsciiString) str =
309 new TCollection_HAsciiString ( col.StringName ( col.Name() ) );
310 colent = new IGESGraph_Color;
311 colent->Init ( col.Red() * 100., col.Green() * 100., col.Blue() * 100., str );
312 AddEntity ( colent );
313 colors.Bind ( c, colent );
316 Handle(Transfer_FinderProcess) FP = TransferProcess();
317 Handle(IGESData_IGESEntity) ent;
318 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
319 if ( FP->FindTypedTransient ( mapper, STANDARD_TYPE(IGESData_IGESEntity), ent ) ) {
320 ent->InitColor ( colent, rank );
321 Handle(IGESSolid_Face) ent_f = Handle(IGESSolid_Face)::DownCast(ent);
324 if (!ent_f->Surface().IsNull())
325 ent_f->Surface()->InitColor ( colent, rank );
329 // may be S was splited during shape process
330 Handle(Transfer_Binder) bnd = FP->Find ( mapper );
331 if ( ! bnd.IsNull() ) {
332 Handle(Transfer_TransientListBinder) TransientListBinder =
333 //Handle(Transfer_TransientListBinder)::DownCast( bnd->Next(Standard_True) );
334 Handle(Transfer_TransientListBinder)::DownCast( bnd );
335 Standard_Integer i=0, nb=0;
336 if (! TransientListBinder.IsNull() ) {
337 nb = TransientListBinder->NbTransients();
338 for (i=1; i<=nb; i++) {
339 Handle(Standard_Transient) t = TransientListBinder->Transient(i);
340 ent = Handle(IGESData_IGESEntity)::DownCast(t);
343 ent->InitColor ( colent, rank );
344 Handle(IGESSolid_Face) ent_f = Handle(IGESSolid_Face)::DownCast(ent);
347 if (!ent_f->Surface().IsNull())
348 ent_f->Surface()->InitColor ( colent, rank );
353 /* // alternative: consider recursive mapping S -> compound -> entities
355 TopoDS_Shape comp = TransferBRep::ShapeResult(bnd);
356 if ( ! comp.IsNull() && comp.ShapeType() < S.ShapeType() )
357 for ( TopoDS_Iterator it(comp); it.More(); it.Next() ) {
358 MakeColors ( it.Value(), settings, colors, Map, style );
366 // iterate on subshapes (except vertices :)
367 if ( S.ShapeType() == TopAbs_EDGE ) return;
368 for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
369 MakeColors ( it.Value(), settings, colors, Map, style );
374 static void AttachLayer (const Handle(Transfer_FinderProcess) &FP,
375 const Handle(XCAFDoc_LayerTool)& LTool,
376 const TopoDS_Shape& aSh,
377 const Standard_Integer localIntName)
380 TopTools_SequenceOfShape shseq;
381 if ( aSh.ShapeType() == TopAbs_COMPOUND ) {
382 TopoDS_Iterator aShIt(aSh);
383 for ( ; aShIt.More(); aShIt.Next() ) {
384 TopoDS_Shape newSh = aShIt.Value();
385 Handle(TColStd_HSequenceOfExtendedString) shLayers = new TColStd_HSequenceOfExtendedString;
386 if (! LTool->GetLayers( newSh, shLayers) || newSh.ShapeType() == TopAbs_COMPOUND )
387 AttachLayer(FP, LTool, newSh, localIntName);
390 } else if ( aSh.ShapeType() == TopAbs_SOLID || aSh.ShapeType() == TopAbs_SHELL ) {
391 for (TopExp_Explorer exp(aSh,TopAbs_FACE) ; exp.More(); exp.Next()) {
392 TopoDS_Face entSh = TopoDS::Face (exp.Current());
399 for (Standard_Integer i = 1; i <= shseq.Length(); i++ ) {
400 TopoDS_Shape localShape = shseq.Value(i);
401 Handle(IGESData_IGESEntity) Igesent;
402 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, localShape );
403 if ( FP->FindTypedTransient ( mapper, STANDARD_TYPE(IGESData_IGESEntity), Igesent ) ) {
404 Igesent->InitLevel( 0, localIntName );
407 else std::cout << "Warning: Can't find entity for shape in mapper" << std::endl;
413 static void MakeLayers (const Handle(Transfer_FinderProcess) &FP,
414 const Handle(XCAFDoc_ShapeTool)& STool,
415 const Handle(XCAFDoc_LayerTool)& LTool,
416 const TDF_LabelSequence& aShapeLabels,
417 const Standard_Integer localIntName)
419 for ( Standard_Integer j = 1; j <= aShapeLabels.Length(); j++ ) {
420 TDF_Label aShapeLabel = aShapeLabels.Value(j);
422 if ( ! STool->GetShape ( aShapeLabel, aSh ) ) continue;
423 AttachLayer (FP, LTool, aSh, localIntName);
429 //=======================================================================
430 //function : WriteLayers
432 //=======================================================================
434 Standard_Boolean IGESCAFControl_Writer::WriteLayers (const TDF_LabelSequence& labels)
436 if ( labels.Length() <=0 ) return Standard_False;
437 Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( labels(1) );
438 if ( STool.IsNull() ) return Standard_False;
439 Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool( labels(1) );
440 if ( LTool.IsNull() ) return Standard_False;
442 Standard_Integer globalIntName = 0;
443 TDF_LabelSequence aLayerLabels;
444 LTool->GetLayerLabels( aLayerLabels );
446 Handle(Transfer_FinderProcess) FP = TransferProcess();
447 for ( Standard_Integer i = 1; i <= aLayerLabels.Length(); i++ ){
448 TDF_Label aOneLayerL = aLayerLabels.Value(i);
449 if ( aOneLayerL.IsNull() ) continue;
450 TCollection_ExtendedString localName;
451 LTool->GetLayer(aOneLayerL, localName);
452 Standard_Integer localIntName = 0;
453 TCollection_AsciiString asciiName(localName,'?');
454 if (asciiName.IsIntegerValue() ) {
455 localIntName = asciiName.IntegerValue();
456 if (globalIntName < localIntName) globalIntName = localIntName;
458 TDF_LabelSequence aShapeLabels;
459 LTool->GetShapesOfLayer( aOneLayerL, aShapeLabels );
460 if ( aShapeLabels.Length() <= 0 ) continue;
461 MakeLayers(FP, STool, LTool, aShapeLabels, localIntName);
465 for ( Standard_Integer i1 = 1; i1 <= aLayerLabels.Length(); i1++ ) {
466 TDF_Label aOneLayerL = aLayerLabels.Value(i1);
467 if ( aOneLayerL.IsNull() ) continue;
468 TCollection_ExtendedString localName;
469 LTool->GetLayer(aOneLayerL, localName);
470 Standard_Integer localIntName = 0;
471 TCollection_AsciiString asciiName(localName,'?');
472 if (asciiName.IsIntegerValue() ) continue;
473 TDF_LabelSequence aShapeLabels;
474 LTool->GetShapesOfLayer( aOneLayerL, aShapeLabels );
475 if ( aShapeLabels.Length() <= 0 ) continue;
476 localIntName = ++globalIntName;
477 MakeLayers (FP, STool, LTool, aShapeLabels, localIntName);
480 return Standard_True;
484 //=======================================================================
485 //function : WriteNames
487 //=======================================================================
489 Standard_Boolean IGESCAFControl_Writer::WriteNames (const TDF_LabelSequence& theLabels)
491 if (theLabels.Length() <= 0) return Standard_False;
493 DataMapOfShapeNames aMapOfShapeNames;
495 for (Standard_Integer anIter = 1; anIter <= theLabels.Length(); anIter++ )
497 TDF_Label aLabel = theLabels.Value (anIter);
500 Handle(TDataStd_Name) aName;
501 if (!XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) continue;
502 if (!aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) continue;
504 aMapOfShapeNames.Bind (aShape, aName->Get());
506 // Collect names for subshapes
507 TopLoc_Location aLocation;
508 CollectShapeNames (aLabel, aLocation, aName, aMapOfShapeNames);
511 for (DataMapOfShapeNames::Iterator anIter (aMapOfShapeNames);
512 anIter.More(); anIter.Next())
514 const TopoDS_Shape& aShape = anIter.Key();
515 const TCollection_ExtendedString& aName = anIter.Value();
517 Handle(Transfer_FinderProcess) aFinderProcess = TransferProcess();
518 Handle(IGESData_IGESEntity) anIGESEntity;
519 Handle(TransferBRep_ShapeMapper) aShapeMapper = TransferBRep::ShapeMapper (aFinderProcess, aShape);
521 if (aFinderProcess->FindTypedTransient (aShapeMapper, STANDARD_TYPE(IGESData_IGESEntity), anIGESEntity))
523 Handle(TCollection_HAsciiString) anAsciiName = new TCollection_HAsciiString (" ");
524 Standard_Integer aNameLength = 8 - aName.Length();
525 if (aNameLength < 0) aNameLength = 0;
526 for (Standard_Integer aCharPos = 1; aNameLength < 8; aCharPos++, aNameLength++)
528 anAsciiName->SetValue (aNameLength+1, IsAnAscii (aName.Value (aCharPos)) ? (Standard_Character )aName.Value (aCharPos) : '?');
530 anIGESEntity->SetLabel (anAsciiName);
532 // Set long IGES name using 406 form 15 entity
533 Handle(IGESBasic_Name) aLongNameEntity = new IGESBasic_Name;
534 Handle(TCollection_HExtendedString) aTmpStr = new TCollection_HExtendedString(aName);
535 aLongNameEntity->Init(1, new TCollection_HAsciiString(aTmpStr, '_'));
537 anIGESEntity->AddProperty(aLongNameEntity);
538 AddEntity(aLongNameEntity);
542 return Standard_True;
545 //=======================================================================
546 //function : SetColorMode
548 //=======================================================================
550 void IGESCAFControl_Writer::SetColorMode (const Standard_Boolean colormode)
552 myColorMode = colormode;
555 //=======================================================================
556 //function : GetColorMode
558 //=======================================================================
560 Standard_Boolean IGESCAFControl_Writer::GetColorMode () const
565 //=======================================================================
566 //function : SetNameMode
568 //=======================================================================
570 void IGESCAFControl_Writer::SetNameMode (const Standard_Boolean namemode)
572 myNameMode = namemode;
575 //=======================================================================
576 //function : GetNameMode
578 //=======================================================================
580 Standard_Boolean IGESCAFControl_Writer::GetNameMode () const
585 //=======================================================================
586 //function : SetLayerMode
588 //=======================================================================
590 void IGESCAFControl_Writer::SetLayerMode (const Standard_Boolean layermode)
592 myLayerMode = layermode;
595 //=======================================================================
596 //function : GetLayerMode
598 //=======================================================================
600 Standard_Boolean IGESCAFControl_Writer::GetLayerMode () const