Integration of OCCT 6.5.0 from SVN
[occt.git] / src / STEPControl / STEPControl_ActorWrite.cxx
CommitLineData
7fd59977 1//:k8 abv 6 Jan 99: unique names for PRODUCTs
2//:k9 abv 6 Jan 99: TR10: eliminating duplicated APPLICATION_CONTEXT entities
3//abv,gka 05.04.99: S4136: change parameters and update units
4// PTV 22.08.2002 OCC609 transfer solo vertices into step file.
5// PTV 16.09.2002 OCC725 transfer compound of vertices into one geometrical curve set.
6#include <STEPControl_ActorWrite.ixx>
7#include <STEPControl_StepModelType.hxx>
8
9// Transfer
10#include <Transfer_SimpleBinderOfTransient.hxx>
11#include <gp_Ax2.hxx>
12#include <GeomToStep_MakeAxis2Placement3d.hxx>
13#include <StepGeom_Axis2Placement3d.hxx>
14
15#include <STEPConstruct_Part.hxx>
16#include <STEPConstruct_Assembly.hxx>
17#include <STEPConstruct_ContextTool.hxx>
18#include <STEPConstruct_UnitContext.hxx>
19
20// TransferShape
21#include <TopoDSToStep.hxx>
22#include <TopoDSToStep_Builder.hxx>
23#include <TopoDSToStep_FacetedTool.hxx>
24#include <TopoDSToStep_Tool.hxx>
25#include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
26#include <TopoDSToStep_MakeBrepWithVoids.hxx>
27#include <TopoDSToStep_MakeFacetedBrep.hxx>
28#include <TopoDSToStep_MakeFacetedBrepAndBrepWithVoids.hxx>
29#include <TopoDSToStep_MakeGeometricCurveSet.hxx>
30#include <TopoDSToStep_MakeShellBasedSurfaceModel.hxx>
31
32#include <TopoDS.hxx>
33#include <TopoDS_Shape.hxx>
34#include <TopoDS_Solid.hxx>
35#include <Geom_Surface.hxx>
36#include <Geom_Plane.hxx>
37#include <Geom_Curve.hxx>
38#include <Geom_Line.hxx>
39
40#include <StepShape_ShapeDefinitionRepresentation.hxx>
41#include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
42#include <StepShape_FacetedBrep.hxx>
43#include <StepShape_GeometricCurveSet.hxx>
44#include <StepShape_ShellBasedSurfaceModel.hxx>
45#include <StepShape_ManifoldSolidBrep.hxx>
46#include <StepShape_BrepWithVoids.hxx>
47#include <StepRepr_HArray1OfRepresentationItem.hxx>
48#include <StepBasic_HArray1OfProduct.hxx>
49#include <StepRepr_GlobalUnitAssignedContext.hxx>
50#include <StepShape_AdvancedBrepShapeRepresentation.hxx>
51#include <StepShape_FacetedBrepShapeRepresentation.hxx>
52#include <StepShape_TopologicalRepresentationItem.hxx>
53#include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
54#include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
55#include <StepBasic_ApplicationProtocolDefinition.hxx>
56#include <StepRepr_PropertyDefinition.hxx>
57
58#include <TopExp_Explorer.hxx>
59#include <TColStd_HSequenceOfTransient.hxx>
60#include <TCollection_HAsciiString.hxx>
61
62#include <Transfer_TransientProcess.hxx>
63#include <Transfer_Binder.hxx>
64#include <Transfer_Finder.hxx>
65#include <Transfer_FinderProcess.hxx>
66#include <TransferBRep_ShapeMapper.hxx>
67#include <TransferBRep.hxx>
68#include <OSD_Timer.hxx>
69
70#include <ShapeExtend_Explorer.hxx>
71#include <ShapeAnalysis_ShapeTolerance.hxx>
72#include <Interface_MSG.hxx>
73#include <Interface_Static.hxx>
74
75#include <Interface_Macros.hxx>
76#include <TopTools_HSequenceOfShape.hxx>
77
78#include <BRep_Tool.hxx>
79#include <TopoDS_Iterator.hxx> //:d6
80#include <UnitsMethods.hxx>
81#include <STEPConstruct_AP203Context.hxx>
82#include <BRepTools_Modifier.hxx>
83
84#include <XSAlgo.hxx>
85#include <XSAlgo_AlgoContainer.hxx>
86#include <StepRepr_ShapeRepresentationRelationship.hxx>
87#include <Transfer_SequenceOfBinder.hxx>
88
89#include <TopoDSToStep_MakeStepVertex.hxx>
90#include <StepShape_VertexPoint.hxx>
91#include <MoniTool_DataMapOfShapeTransient.hxx>
92#include <StepShape_HArray1OfGeometricSetSelect.hxx>
93#include <StepShape_GeometricSetSelect.hxx>
94#include <TopoDS_Compound.hxx>
95#include <BRep_Builder.hxx>
96
97// Non-manifold topology processing (ssv; 10.11.2010)
98#include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
99#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
100#include <TopTools_ListOfShape.hxx>
101#include <TopExp.hxx>
102#include <TopTools_MapOfShape.hxx>
103#include <TopTools_ListIteratorOfListOfShape.hxx>
104
105// ============================================================================
106// Function: DumpWhatIs
107// Purpose: Use it in DEB mode to dump your shapes
108// ============================================================================
109
110static void DumpWhatIs(const TopoDS_Shape& S) {
111
112 TopTools_MapOfShape aMapOfShape;
113 aMapOfShape.Add(S);
114 TopTools_ListOfShape aListOfShape;
115 aListOfShape.Append(S);
116 TopTools_ListIteratorOfListOfShape itL(aListOfShape);
117 Standard_Integer nbSolids = 0,
118 nbShells = 0,
119 nbOpenShells = 0,
120 nbFaces = 0,
121 nbWires = 0,
122 nbEdges = 0,
123 nbVertexes = 0;
124
125 for( ; itL.More(); itL.Next() ) {
126 TopoDS_Iterator it( itL.Value() );
127 for ( ; it.More(); it.Next() ) {
128 TopoDS_Shape aSubShape = it.Value();
129 if ( !aMapOfShape.Add(aSubShape) )
130 continue;
131 aListOfShape.Append(aSubShape);
132 if (aSubShape.ShapeType() == TopAbs_SOLID)
133 nbSolids++;
134 if (aSubShape.ShapeType() == TopAbs_SHELL) {
135 if ( !aSubShape.Closed() )
136 nbOpenShells++;
137 nbShells++;
138 }
139 if (aSubShape.ShapeType() == TopAbs_FACE)
140 nbFaces++;
141 if (aSubShape.ShapeType() == TopAbs_WIRE)
142 nbWires++;
143 if (aSubShape.ShapeType() == TopAbs_EDGE)
144 nbEdges++;
145 if (aSubShape.ShapeType() == TopAbs_VERTEX)
146 nbVertexes++;
147 }
148 }
149 #ifdef DEB
150 cout << "//What is?// NB SOLIDS: " << nbSolids << endl;
151 cout << "//What is?// NB SHELLS: " << nbShells << endl;
152 cout << "//What is?// OPEN SHELLS: " << nbOpenShells << endl;
153 cout << "//What is?// CLOSED SHELLS: " << nbShells - nbOpenShells << endl;
154 cout << "//What is?// NB FACES: " << nbFaces << endl;
155 cout << "//What is?// NB WIRES: " << nbWires << endl;
156 cout << "//What is?// NB EDGES: " << nbEdges << endl;
157 cout << "//What is?// NB VERTEXES: " << nbVertexes << endl;
158 #endif
159}
160
161//=======================================================================
162// Function : IsManifoldShape
163// Purpose : Used to define whether the passed shape has manifold
164// topology or not
165//=======================================================================
166
167static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
168
169 Standard_Boolean aResult = Standard_True;
170
171 // Do not check nested Compounds
172 TopoDS_Compound aDirectShapes;
173 BRep_Builder aBrepBuilder;
174 aBrepBuilder.MakeCompound(aDirectShapes);
175
176 TopoDS_Iterator anIt(theShape);
177 for ( ; anIt.More(); anIt.Next() ) {
178 TopoDS_Shape aDirectChild = anIt.Value();
179 if (aDirectChild.ShapeType() != TopAbs_COMPOUND)
180 aBrepBuilder.Add(aDirectShapes, aDirectChild);
181 }
182
183 #ifdef DEB
184 DumpWhatIs(aDirectShapes);
185 #endif
186
187 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
188 TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
189
190 Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
191 #ifdef DEB
192 cout << "Checking whether the topology passed is manifold..." << endl;
193 #endif
194
195 // Check topology
196 for (Standard_Integer i = 1; i <= aNbEdges; i++) {
197 TopoDS_Edge aCurrentEdge = TopoDS::Edge( aMapEdgeFaces.FindKey(i) );
198 if ( !BRep_Tool::Degenerated(aCurrentEdge) ) {
199 Standard_Integer aNbAncestors = aMapEdgeFaces.FindFromIndex(i).Extent();
200 if (aNbAncestors > 2) {
201 aResult = Standard_False;
202 break;
203 }
204 }
205 }
206
207 #ifdef DEB
208 cout << "Check result: "
209 << (aResult ? "TRUE" : "FALSE") << endl;
210 #endif
211
212 return aResult;
213}
214
215/* this is a start of a comment! */
216#ifdef DEB
217void DumpBinder (const Handle(Transfer_Binder) &binder)
218{
219 Handle(Transfer_Binder) bbb = binder;
220 while ( ! bbb.IsNull() ) {
221 Handle(Transfer_SimpleBinderOfTransient) bx =
222 Handle(Transfer_SimpleBinderOfTransient)::DownCast ( bbb );
223 cout << (void*)&bx;
224 if ( ! bx.IsNull() ) {
225 cout << "--> " << bx->ResultTypeName() << " " << *(void**)&bx->Result() << endl;
226 }
227 else cout << "--> ???" << endl;
228 bbb = bbb->NextResult();
229 }
230 cout << endl;
231}
232#endif
233/* this is a end of a comment */
234
235//=======================================================================
236//function : STEPControl_ActorWrite
237//purpose :
238//=======================================================================
239
240STEPControl_ActorWrite::STEPControl_ActorWrite ()
241: mygroup (0) , mytoler (-1.)
242{
243 SetMode(STEPControl_ShellBasedSurfaceModel);
244}
245
246//=======================================================================
247//method: getNMSSRForGroup
248//purpose: allows to get NMSSR (NON_MANIFOLD_SURFACE_SHAPE_REPRESENTATION)
249// STEP's entity for the group of shells (!) passed
250//=======================================================================
251
252Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::getNMSSRForGroup(const Handle(TopTools_HSequenceOfShape)& shapeGroup,
253 const Handle(Transfer_FinderProcess)& FP,
254 Standard_Boolean& isNMSSRCreated) const
255{
256 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) aResult;
257
258 if ( !shapeGroup.IsNull() ) {
259 for (Standard_Integer i = 1; i <= shapeGroup->Length(); i++) {
260 TopoDS_Shape aCurrentShape = shapeGroup->Value(i);
261 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper(FP, aCurrentShape);
262 if ( FP->FindTypedTransient(mapper, STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation), aResult) )
263 break;
264 }
265 }
266
267 if ( aResult.IsNull() ) {
268 #ifdef DEB
269 cout << "\nNew NMSSR created" << endl;
270 #endif
271 aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
272 isNMSSRCreated = Standard_True;
273 } else {
274 #ifdef DEB
275 cout << "\nExisting NMSSR is used" << endl;
276 #endif
277 isNMSSRCreated = Standard_False;
278 }
279
280 return aResult;
281}
282
283
284//=======================================================================
285//function : SetMode
286//purpose :
287//=======================================================================
288
289void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
290{
291 switch (M) {
292 case STEPControl_AsIs : ModeTrans() = 0; break;
293 case STEPControl_ManifoldSolidBrep : ModeTrans() = 3; break;
294 case STEPControl_BrepWithVoids : ModeTrans() = 5; break;
295 case STEPControl_FacetedBrep : ModeTrans() = 1; break;
296 case STEPControl_FacetedBrepAndBrepWithVoids : ModeTrans() = 6; break;
297 case STEPControl_ShellBasedSurfaceModel : ModeTrans() = 2;
298 case STEPControl_GeometricCurveSet : ModeTrans() = 4;
299 case STEPControl_Hybrid : ModeTrans() = 0; break; // PAS IMPLEMENTE !!
300 default: break;
301 }
302}
303
304//=======================================================================
305//function : Mode
306//purpose :
307//=======================================================================
308
309STEPControl_StepModelType STEPControl_ActorWrite::Mode () const
310{
311 switch (themodetrans) {
312 case 0 : return STEPControl_AsIs;
313 case 1 : return STEPControl_FacetedBrep;
314 case 2 : return STEPControl_ShellBasedSurfaceModel;
315 case 3 : return STEPControl_ManifoldSolidBrep;
316 case 4 : return STEPControl_GeometricCurveSet;
317 case 5 : return STEPControl_BrepWithVoids;
318 case 6 : return STEPControl_FacetedBrepAndBrepWithVoids;
319 default : break;
320 }
321 return STEPControl_AsIs;
322}
323
324//=======================================================================
325//function : SetGroupMode
326//purpose :
327//=======================================================================
328
329void STEPControl_ActorWrite::SetGroupMode (const Standard_Integer mode)
330{
331 if (mode >= 0) mygroup = mode;
332}
333
334//=======================================================================
335//function : GroupMode
336//purpose :
337//=======================================================================
338
339Standard_Integer STEPControl_ActorWrite::GroupMode () const
340{
341 return mygroup;
342}
343
344//=======================================================================
345//function : SetTolerance
346//purpose :
347//=======================================================================
348
349void STEPControl_ActorWrite::SetTolerance (const Standard_Real Tol)
350{
351 mytoler = Tol;
352}
353
354//=======================================================================
355//function : Recognize
356// ATTENTION, Recognize doit s aligner sur ce que Transfer sait faire
357//purpose :
358//=======================================================================
359
360Standard_Boolean STEPControl_ActorWrite::Recognize (const Handle(Transfer_Finder)& start)
361{
362 STEPControl_StepModelType mymode = Mode();
363 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
364 if (mapper.IsNull()) return Standard_False;
365 if (mymode == STEPControl_AsIs) return Standard_True;
366
367 Standard_Boolean yasolid = Standard_False, yashell = Standard_False,
368 yaface = Standard_False;
369
370 TopoDS_Shape theShape, aShape;
371// theShape = TopoDSToStep::DirectFaces(mapper->Value());
372 theShape = mapper->Value(); // pour une reconnaissance c est bien assez
373
374 if (theShape.ShapeType() == TopAbs_COMPOUND) {
375
376 TopExp_Explorer SolidExp, ShellExp, FaceExp;
377
378 for (SolidExp.Init(theShape, TopAbs_SOLID);
379 SolidExp.More();SolidExp.Next()) yasolid = Standard_True;
380 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
381 ShellExp.More();ShellExp.Next()) yashell = Standard_True;
382 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
383 FaceExp.More();FaceExp.Next()) yaface = Standard_True;
384 }
385 else if (theShape.ShapeType() == TopAbs_SOLID) yasolid = Standard_True;
386 else if (theShape.ShapeType() == TopAbs_SHELL) yashell = Standard_True;
387 else if (theShape.ShapeType() == TopAbs_FACE) yaface = Standard_True;
388 else if (mymode != STEPControl_GeometricCurveSet) return Standard_False;
389// pour wireframe ?
390
391// Faceted : il est OBLIGATOIRE d avoir des surfaces support Plane et des
392// courbes 3D Line (pcurves ignorees)
393
394 if (mymode == STEPControl_FacetedBrep || mymode == STEPControl_FacetedBrepAndBrepWithVoids) {
395 for (TopExp_Explorer ffac(theShape,TopAbs_FACE); ffac.More(); ffac.Next()) {
396 const TopoDS_Face& F = TopoDS::Face (ffac.Current());
397 TopLoc_Location locbid;
398 Handle(Geom_Surface) surf = BRep_Tool::Surface (F,locbid);
399 if (surf.IsNull() || !surf->IsKind(STANDARD_TYPE(Geom_Plane)) ) return Standard_False;
400 }
401 for (TopExp_Explorer fedg(theShape,TopAbs_EDGE); fedg.More(); fedg.Next()) {
402 const TopoDS_Edge& E = TopoDS::Edge (fedg.Current());
403 TopLoc_Location locbid; Standard_Real first,last;
404 Handle(Geom_Curve) curv = BRep_Tool::Curve (E,locbid,first,last);
405 if (curv.IsNull() || !curv->IsKind(STANDARD_TYPE(Geom_Line)) ) return Standard_False;
406 }
407 }
408
409 switch (mymode) {
410 case STEPControl_ManifoldSolidBrep: return (yasolid || yashell);
411 case STEPControl_BrepWithVoids:
412 case STEPControl_FacetedBrep:
413 case STEPControl_FacetedBrepAndBrepWithVoids: return yasolid;
414 case STEPControl_ShellBasedSurfaceModel:
415 return (yasolid || yashell || yaface);
416 case STEPControl_GeometricCurveSet: return Standard_True; // tout OK
417 default : break;
418 }
419 return Standard_False;
420}
421
422
423// ######## MAKE PRODUCT DATA + CONTEXT ########
424
425//=======================================================================
426//function : Transfer
427//purpose :
428//=======================================================================
429
430Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_Finder)& start,
431 const Handle(Transfer_FinderProcess)& FP)
432{
433 XSAlgo::AlgoContainer()->PrepareForTransfer();
434
435 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
436
437 if (mapper.IsNull()) return NullResult();
438 TopoDS_Shape shape = mapper->Value();
439
440 // init context
441 Handle(StepData_StepModel) model = Handle(StepData_StepModel)::DownCast ( FP->Model() );
442 if ( ! model.IsNull() ) myContext.SetModel ( model ); //: abv 04.11.00: take APD from model
443 myContext.AddAPD ( Standard_False ); // update APD
444 myContext.SetLevel ( 1 ); // set assembly level to 1 (to ensure)
445
446 //:S4136: init UnitsMethods to reset angle unit factors (see TopoDSToStep)
447 Standard_Real lFactor = UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) );
448 lFactor /= UnitsMethods::GetCasCadeLengthUnit();
449 Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
450 UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : PI/180. ), 1. );
451
452 // create SDR
453 STEPConstruct_Part SDRTool;
454 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
455 Handle(StepShape_ShapeDefinitionRepresentation) sdr = SDRTool.SDRValue();
456 // transfer shape
457
458 Handle(Transfer_Binder) resbind = TransferShape (mapper,sdr,FP);
459
460// Handle(StepShape_ShapeRepresentation) resultat;
461// FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
462// sdr->SetUsedRepresentation (resultat);
463
464 // create binder with all root entities produced from shape
465 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForPart ( SDRTool );
466 Handle(Transfer_Binder) resprod = TransientResult ( myContext.GetAPD() );
467 for ( Standard_Integer i=1; i <= roots->Length(); i++ )
468 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
469 resprod->AddResult(resbind);
470
471 // bind and exit
472 //FP->Bind (mapper,resprod);
473 myContext.NextIndex();
474 return resprod;
475}
476
477//==========================================
478
479static Standard_Real UsedTolerance (const Standard_Real mytoler,
480 const TopoDS_Shape& theShape)
481{
482
483 // COMPUTING 3D TOLERANCE
484 // Either from Session, or Computed (Least,Average, or Greatest)
485 // Then given to TopoDSToStep_Tool
486
487 Standard_Real Tol = mytoler;
488 Standard_Integer tolmod = Interface_Static::IVal("write.precision.mode");
489 if (Tol <= 0 && tolmod == 2) Tol =
490 Interface_Static::RVal("write.precision.val");
491 if (Tol <= 0) {
492 ShapeAnalysis_ShapeTolerance stu;
493 Tol = stu.Tolerance (theShape,tolmod);
494 // Par defaut, on prend une tolerance moyenne, on elimine les aberrations
495 Tol = Interface_MSG::Intervalled (Tol * 1.5); // arrondi a 1 2 5 ...
496 }
497 if (Tol == 0) Tol = 1.e-07; // minimum ...
498
499 return Tol;
500}
501
502//=======================================================================
503//function : IsAssembly
504//purpose :
505//=======================================================================
506// if GroupMode is >1 downgrades all compounds having single subshape to that
507// subshape
508
509Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
510{
511 if ( ! GroupMode() || S.ShapeType() != TopAbs_COMPOUND ) return Standard_False;
512 // PTV 16.09.2002 OCC725 for storing compound of vertices
513 if (S.ShapeType() == TopAbs_COMPOUND ) {
514 Standard_Boolean IsOnlyVertices = Standard_True;
515 TopoDS_Iterator anItr( S );
516 for ( ; anItr.More(); anItr.Next() ) {
517 if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
518 IsOnlyVertices = Standard_False;
519 break;
520 }
521 }
522 if ( IsOnlyVertices )
523 return Standard_False;
524 }
525 if ( GroupMode() ==1 ) return Standard_True;
526 TopoDS_Iterator it ( S );
527 if ( ! it.More() ) return Standard_False;
528 TopoDS_Shape shape = it.Value();
529 it.Next();
530 if ( it.More() ) return Standard_True;
531 S = shape;
532 return IsAssembly ( S );
533}
534
535//=======================================================================
536//function : TransferShape
537//purpose :
538//=======================================================================
539
540/*
541static void UpdateMap (const TopoDS_Shape &shape,
542 BRepTools_Modifier &M1,
543 BRepTools_Modifier &M2,
544 const Handle(Transfer_FinderProcess) &FinderProcess)
545{
546 TopoDS_Shape S = M1.ModifiedShape ( shape );
547 S = M2.ModifiedShape ( S );
548 if ( S == shape ) return;
549
550 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess, S );
551 Handle(Transfer_Binder) binder = FinderProcess->Find ( mapper );
552 if ( ! binder.IsNull() ) {
553 mapper = TransferBRep::ShapeMapper ( FinderProcess, shape );
554 FinderProcess->Bind ( mapper, binder );
555 }
556
557 for ( TopoDS_Iterator it(shape); it.More(); it.Next() )
558 UpdateMap ( it.Value(), M1, M2, FinderProcess );
559}
560*/
561
562// PTV 16.09.2002 added for transfering vertices.
563static Standard_Boolean transferVertex (const Handle(Transfer_FinderProcess)& FP,
564 Handle(StepShape_HArray1OfGeometricSetSelect)& aGSS,
565 const TopoDS_Shape& aShVrtx,
566 const Standard_Integer theNum)
567{
568 Standard_Boolean IsDone = Standard_False;
569 MoniTool_DataMapOfShapeTransient aMap;
570 TopoDSToStep_Tool aTool(aMap, Standard_True);
571 TopoDSToStep_MakeStepVertex aMkVrtx ( TopoDS::Vertex(aShVrtx), aTool, FP );
572
573 if (!aMkVrtx.IsDone())
574 return IsDone;
575
576 Handle(StepShape_VertexPoint) aVP =
577 Handle(StepShape_VertexPoint)::DownCast(aTool.Find(aShVrtx));
578 if (aVP.IsNull())
579 return IsDone;
580
581 StepShape_GeometricSetSelect select;
582 select.SetValue(aVP->VertexGeometry());
583 // add current result
584 aGSS->SetValue( theNum, select );
585 IsDone = Standard_True;
586 return IsDone;
587}
588
589
590Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Transfer_Finder)& start,
591 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
592 const Handle(Transfer_FinderProcess)& FP,
593 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
594 const Standard_Boolean isManifold)
595{
596 STEPControl_StepModelType mymode = Mode();
597 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
598 Handle(Transfer_Binder) binder;
599
600 // Indicates whether to use an exising NMSSR to write items to (ss; 13.11.2010)
601 Standard_Boolean useExistingNMSSR = Standard_False;
602
603 if (mapper.IsNull()) return binder;
604 TopoDS_Shape theShape = mapper->Value();
605
606 if (theShape.IsNull()) return binder;
607
608 // INDIVIDUAL SHAPE ALREADY TRANSFERRED : RETURN IT !
609 binder = FP->Find(start);
610 if (!binder.IsNull()) { if (!binder->HasResult()) binder.Nullify(); }
611 if (!binder.IsNull()) {
612 //:abv 20.05.02: writing box & face from it (shared) in one compound
613 // as assembly - while face already translated, it should be
614 // re-translated to break sharing
615#ifdef DEB
616 cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << endl;
617#endif
618// return binder;
619 }
620
621 // MODE ASSEMBLY : if Compound, (sub-)assembly
622 if ( IsAssembly(theShape) )
623 return TransferCompound(start, SDR0, FP);
624
625 // [BEGIN] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
626 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
627 Handle(Transfer_Binder) aNMBinder;
628 if (isNMMode && !GroupMode() && theShape.ShapeType() == TopAbs_COMPOUND) {
629 TopoDS_Compound aNMCompound;
630 TopoDS_Compound aManifoldCompound;
631 BRep_Builder brepBuilder;
632
633 // Create empty Compounds
634 brepBuilder.MakeCompound(aManifoldCompound);
635 brepBuilder.MakeCompound(aNMCompound);
636
637 // Indicates whether there is only non-manifold topology detected
638 // (there is no manifold topology found in the Compound passed)
639 Standard_Boolean isOnlyNonManifold = Standard_False;
640
641 // Find a Compound containing non-manifold topology.
642 // NOTE: only one such Compound must exist in the entire Compound passed
643 if ( !IsManifoldShape(theShape) ) {
644 aNMCompound = TopoDS::Compound(theShape);
645 isOnlyNonManifold = Standard_True;
646 }
647 else {
648 TopTools_ListOfShape aListOfShapes;
649 TopTools_ListOfShape aListOfManifoldShapes;
650 aListOfShapes.Append(theShape);
651
652 TopTools_ListIteratorOfListOfShape itL(aListOfShapes);
653 for ( ; itL.More(); itL.Next() ) {
654 TopoDS_Shape aParentShape = itL.Value();
655 TopoDS_Iterator it(aParentShape);
656 for ( ; it.More(); it.Next() ) {
657 TopoDS_Shape aSubShape = it.Value();
658 if (aSubShape.ShapeType() == TopAbs_COMPOUND && !IsManifoldShape(aSubShape) )
659 aNMCompound = TopoDS::Compound(aSubShape);
660 else if (aSubShape.ShapeType() == TopAbs_COMPOUND)
661 aListOfShapes.Append(aSubShape);
662 else
663 aListOfManifoldShapes.Append(aSubShape);
664 }
665 }
666
667 // Group manifold topology together.
668 // NOTE: there is no sense that initial Compound structure was lost as
669 // group mode is set to 0 (no Assemblies are mapped)
670 for ( itL.Initialize(aListOfManifoldShapes); itL.More(); itL.Next() ) {
671 TopoDS_Shape aCurrentManiShape = itL.Value();
672 brepBuilder.Add(aManifoldCompound, aCurrentManiShape);
673 }
674
675 }
676
677 // Process only manifold topology in the current TransferShape invocation.
678 // Invoke TransferShape for non-manifold topology separately (see below)
679 theShape = aManifoldCompound;
680
681 // List of items to transfer
682 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
683 // Non-manifold group to pass into TransferShape with each shape from RepItemSeq
684 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
685
686 // Transfer Solids to closed Shells. Prepare RepItemSeq & NonManifoldGroup
687 for ( TopoDS_Iterator iter(aNMCompound); iter.More(); iter.Next() ) {
688 TopoDS_Shape aSubShape = iter.Value();
689 if (aSubShape.ShapeType() == TopAbs_SOLID) {
690 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
691 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
692 aSubShell.Closed(Standard_True);
693 RepItemSeq->Append(aSubShell);
694 NonManifoldGroup->Append(aSubShell);
695 }
696 }
697 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
698 RepItemSeq->Append(aSubShape);
699 NonManifoldGroup->Append(aSubShape);
700 }
701 else
702 RepItemSeq->Append( iter.Value() );
703 }
704
705 Standard_Integer aNMItemsNb = RepItemSeq->Length();
706
707 // In case of pure manifold topology do nothing; theShape is processed as usual (see below)
708 if (aNMItemsNb > 0) {
709
710 // Prepare SDR for non-manifold group. This SDR will be linked to NMSSR by means
711 // of TransferShape invocation. SDR is not created if there is no any manifold
712 // topology in the passed Compound. If topology is pure non-manifold, SDR0 (passed)
713 // is used
714 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
715 if (isOnlyNonManifold)
716 sdr = SDR0;
717 else {
718 STEPConstruct_Part SDRTool;
719 SDRTool.MakeSDR( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
720 sdr = SDRTool.SDRValue();
721 }
722
723 aNMBinder = TransientResult(sdr);
724
725 // Complete SDR with shape representations.
726 // NOTE: aNMBinder is connected now with this SDR. It will be added to the resulting
727 // binder in the end of this invocation of TransferShape
728 for (Standard_Integer i = 1; i <= aNMItemsNb; i++) {
729 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
730 TransferShape(mapper, sdr, FP, NonManifoldGroup, Standard_False);
731 }
732
733 // Nothing else needed for pure non-manifold topology, return
734 if (isOnlyNonManifold)
735 return aNMBinder;
736
737 }
738
739 }
740 // [END] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
741
742 // create a list of items to translate
743 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
744
745 // PTV 16.09.2002 OCC725 separate shape from solo vertices.
746 if (theShape.ShapeType() == TopAbs_COMPOUND) {
747 Standard_Integer countVrtx = 0;
748 Standard_Integer countSh = 0;
749 TopoDS_Compound aNewShape, aCompOfVrtx;
750 BRep_Builder aB;
751 aB.MakeCompound(aNewShape);
752 aB.MakeCompound(aCompOfVrtx);
753 TopoDS_Iterator anCompIt(theShape);
754 for (; anCompIt.More(); anCompIt.Next()) {
755 TopoDS_Shape aCurSh = anCompIt.Value();
756 if (aCurSh.ShapeType() != TopAbs_VERTEX) {
757 aB.Add(aNewShape, aCurSh);
758 countSh++;
759 }
760 else {
761 aB.Add(aCompOfVrtx, aCurSh);
762 countVrtx++;
763 }
764 }
765 // replace the shapes
766 if (countSh)
767 theShape = aNewShape;
768 if (countVrtx)
769 RepItemSeq->Append(aCompOfVrtx);
770 }
771 else if (theShape.ShapeType() == TopAbs_VERTEX)
772 RepItemSeq->Append(theShape); // to translate one vertex
773
774
775 if (theShape.ShapeType() == TopAbs_COMPOUND) {
776 TopExp_Explorer SolidExp, ShellExp, FaceExp;
777 if (mymode != STEPControl_GeometricCurveSet) {
778 for (SolidExp.Init(theShape, TopAbs_SOLID);
779 SolidExp.More();SolidExp.Next()) {
780 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
781 }
782 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
783 ShellExp.More();ShellExp.Next()) {
784 RepItemSeq->Append(TopoDS::Shell(ShellExp.Current()));
785 }
786
787 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
788 FaceExp.More();FaceExp.Next()) {
789 RepItemSeq->Append(TopoDS::Face(FaceExp.Current()));
790 }
791 }
792 else {
793 RepItemSeq->Append(theShape); //:j1
794 }
795 if(mymode == STEPControl_AsIs) {
796 TopExp_Explorer WireExp, EdgeExp;
797 for (WireExp.Init(theShape, TopAbs_WIRE, TopAbs_FACE);
798 WireExp.More();WireExp.Next())
799 RepItemSeq->Append(TopoDS::Wire(WireExp.Current()));
800 for (EdgeExp.Init(theShape, TopAbs_EDGE, TopAbs_WIRE);
801 EdgeExp.More();EdgeExp.Next())
802 RepItemSeq->Append(TopoDS::Edge(EdgeExp.Current()));
803 }
804
805 }
806 else if (theShape.ShapeType() == TopAbs_SOLID) {
807 RepItemSeq->Append(TopoDS::Solid(theShape));
808 }
809 else if (theShape.ShapeType() == TopAbs_SHELL) {
810 RepItemSeq->Append(TopoDS::Shell(theShape));
811 }
812 else if (theShape.ShapeType() == TopAbs_FACE) {
813 RepItemSeq->Append(TopoDS::Face(theShape));
814 }
815 else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
816 FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
817 return binder;
818 }
819 else RepItemSeq->Append (theShape);
820
821 // COMPUTING 3D TOLERANCE
822 // Either from Session, or Computed (Least,Average, or Greatest)
823 // Then given to TopoDSToStep_Tool
824 Standard_Real Tol = UsedTolerance (mytoler,theShape);
825
826 // Create a STEP-Entity for each TopoDS_Shape
827 // according to the current StepModelMode
828
829 Standard_Integer nbs = RepItemSeq->Length();
830 Handle(TColStd_HSequenceOfTransient) ItemSeq =
831 new TColStd_HSequenceOfTransient();
832
833//ptv 10.11.00: allow to write empty Compound: if (GroupMode() >0)
834 ItemSeq->Append (myContext.GetDefaultAxis());
835 STEPControl_StepModelType trmode = mymode;
836 for (Standard_Integer i = 1; i <= nbs; i++) {
837 TopoDS_Shape xShape = RepItemSeq->Value(i);
838
839 if(mymode == STEPControl_AsIs) {
840 switch(xShape.ShapeType()) {
841 case TopAbs_SOLID : trmode = STEPControl_ManifoldSolidBrep;break;
842 case TopAbs_SHELL : trmode = STEPControl_ShellBasedSurfaceModel; break;
843 case TopAbs_FACE : trmode = STEPControl_ShellBasedSurfaceModel;break;
844 default : trmode =STEPControl_GeometricCurveSet; break;
845 }
846 }
847 //:abv 24Jan99 CAX-IF TRJ3: expanded Shape Processing
848// TopoDS_Shape aShape = xShape;
849 // eliminate conical surfaces with negative semiangles
850// Handle(TopoDSToStep_ConicalSurfModif) CSM = new TopoDSToStep_ConicalSurfModif();
851// BRepTools_Modifier CSMT(aShape,CSM);
852// if ( CSMT.IsDone() ) aShape = CSMT.ModifiedShape ( aShape );
853// // eliminate indirect elementary surfaces
854// Handle(TopoDSToStep_DirectModification) DM = new TopoDSToStep_DirectModification();
855// BRepTools_Modifier DMT(aShape,DM);
856// if ( DMT.IsDone() ) aShape = DMT.ModifiedShape ( aShape );
857//// aShape = TopoDSToStep::DirectFaces(xShape);
858 Handle(Standard_Transient) info;
859 Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
860
861 // Fix only manifold shapes, do nothing with non-manifold topology as it is processed separately (ssv; 13.11.2010)
862 TopoDS_Shape aShape;
863 if (isManifold)
864 aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol,
865 "write.step.resource.name",
866 "write.step.sequence", info);
867 else
868 aShape = xShape;
869
870 // create a STEP entity corresponding to shape
871 Handle(StepGeom_GeometricRepresentationItem) item;
872 switch (trmode)
873 {
874 case STEPControl_ManifoldSolidBrep:
875 {
876 if (aShape.ShapeType() == TopAbs_SOLID) {
877 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
878
879 //:d6 abv 13 Mar 98: if solid has more than 1 shell,
880 // try to treat it as solid with voids
881 Standard_Integer nbShells = 0;
882 for ( TopoDS_Iterator It ( aSolid ); It.More(); It.Next() )
883 if (It.Value().ShapeType() == TopAbs_SHELL) nbShells++;
884 if ( nbShells >1 ) {
885 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
886 MkBRepWithVoids.Tolerance() = Tol;
887 if (MkBRepWithVoids.IsDone()) {
888 item = MkBRepWithVoids.Value();
889 }
890 else nbShells = 1; //smth went wrong; let it will be just Manifold
891 }
892 if ( nbShells ==1 ) {
893
894 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aSolid,FP);
895 MkManifoldSolidBrep.Tolerance() = Tol;
896 if (MkManifoldSolidBrep.IsDone()) {
897 item = MkManifoldSolidBrep.Value();
898 }
899 }
900 }
901 else if (aShape.ShapeType() == TopAbs_SHELL) {
902 TopoDS_Shell aShell = TopoDS::Shell(aShape);
903 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aShell,FP);
904 MkManifoldSolidBrep.Tolerance() = Tol;
905 if (MkManifoldSolidBrep.IsDone()) {
906 item = MkManifoldSolidBrep.Value();
907 }
908 }
909 break;
910 }
911 case STEPControl_BrepWithVoids:
912 {
913 if (aShape.ShapeType() == TopAbs_SOLID) {
914 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
915 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
916 MkBRepWithVoids.Tolerance() = Tol;
917 if (MkBRepWithVoids.IsDone()) {
918 item = MkBRepWithVoids.Value();
919 }
920 }
921 break;
922 }
923 case STEPControl_FacetedBrep:
924 {
925 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
926 if (facErr != TopoDSToStep_FacetedDone) {
927 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
928 if (facErr == TopoDSToStep_SurfaceNotPlane) {
929 FP->AddFail(start,"-- The TopoDS_Face is not plane");
930 }
931 else if (facErr == TopoDSToStep_PCurveNotLinear) {
932 FP->AddFail(start,"-- The Face contains non linear PCurves");
933 }
934 return binder;
935 }
936 if (aShape.ShapeType() == TopAbs_SOLID) {
937 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
938 TopoDSToStep_MakeFacetedBrep MkFacetedBrep(aSolid,FP);
939 MkFacetedBrep.Tolerance() = Tol;
940 if (MkFacetedBrep.IsDone()) {
941 item = MkFacetedBrep.Value();
942 }
943 }
944 break;
945 }
946 case STEPControl_FacetedBrepAndBrepWithVoids:
947 {
948 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
949 if (facErr != TopoDSToStep_FacetedDone) {
950 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
951 if (facErr == TopoDSToStep_SurfaceNotPlane) {
952 FP->AddFail(start,"-- The TopoDS_Face is not plane");
953 }
954 else if (facErr == TopoDSToStep_PCurveNotLinear) {
955 FP->AddFail(start,"-- The Face contains non linear PCurves");
956 }
957 return binder;
958 }
959 if (aShape.ShapeType() == TopAbs_SOLID) {
960 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
961 TopoDSToStep_MakeFacetedBrepAndBrepWithVoids
962 MkFacetedBrepAndBrepWithVoids(aSolid,FP);
963 MkFacetedBrepAndBrepWithVoids.Tolerance() = Tol;
964 if (MkFacetedBrepAndBrepWithVoids.IsDone()) {
965 item = MkFacetedBrepAndBrepWithVoids.Value();
966 }
967 }
968 break;
969 }
970 case STEPControl_ShellBasedSurfaceModel:
971 {
972 if (aShape.ShapeType() == TopAbs_SOLID) {
973 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
974 TopoDSToStep_MakeShellBasedSurfaceModel
975 MkShellBasedSurfaceModel(aSolid, FP);
976 MkShellBasedSurfaceModel.Tolerance() = Tol;
977 if (MkShellBasedSurfaceModel.IsDone()) {
978 item = MkShellBasedSurfaceModel.Value();
979 }
980 }
981 else if (aShape.ShapeType() == TopAbs_SHELL) {
982 TopoDS_Shell aShell = TopoDS::Shell(aShape);
983 // Non-manifold topology is stored via NMSSR containing series of SBSM (ssv; 13.11.2010)
984 TopoDSToStep_MakeShellBasedSurfaceModel MkShellBasedSurfaceModel(aShell, FP);
985 MkShellBasedSurfaceModel.Tolerance() = Tol;
986 if (MkShellBasedSurfaceModel.IsDone()) {
987 item = MkShellBasedSurfaceModel.Value();
988 }
989 }
990 else if (aShape.ShapeType() == TopAbs_FACE) {
991 TopoDS_Face aFace = TopoDS::Face(aShape);
992 TopoDSToStep_MakeShellBasedSurfaceModel
993 MkShellBasedSurfaceModel(aFace, FP);
994 MkShellBasedSurfaceModel.Tolerance() = Tol;
995 if (MkShellBasedSurfaceModel.IsDone()) {
996 item = MkShellBasedSurfaceModel.Value();
997 }
998 }
999 break;
1000 }
1001 case STEPControl_GeometricCurveSet:
1002 {
1003 TopoDSToStep_MakeGeometricCurveSet MkGeometricCurveSet(aShape,FP);
1004 MkGeometricCurveSet.Tolerance() = Tol;
1005 if (MkGeometricCurveSet.IsDone()) {
1006 item = MkGeometricCurveSet.Value();
1007 }
1008 // PTV 22.08.2002 OCC609 ------------------------- begin --------------------
1009 // modified by PTV 16.09.2002 OCC725
1010 else if (aShape.ShapeType() == TopAbs_COMPOUND ||
1011 aShape.ShapeType() == TopAbs_VERTEX) {
1012 // it is compund with solo vertices.
1013 Standard_Integer aNbVrtx = 0;
1014 Standard_Integer curNb = 0;
1015 TopExp_Explorer anExp (aShape, TopAbs_VERTEX);
1016 for ( ; anExp.More(); anExp.Next() ) {
1017 if ( anExp.Current().ShapeType() != TopAbs_VERTEX )
1018 continue;
1019 aNbVrtx++;
1020 }
1021 if ( aNbVrtx ) {
1022 // create new geometric curve set for all vertices
1023 Handle(StepShape_HArray1OfGeometricSetSelect) aGSS =
1024 new StepShape_HArray1OfGeometricSetSelect(1,aNbVrtx);
1025 Handle(TCollection_HAsciiString) empty = new TCollection_HAsciiString("");
1026 Handle(StepShape_GeometricCurveSet) aGCSet =
1027 new StepShape_GeometricCurveSet;
1028 aGCSet->SetName(empty);
1029 // iterates on compound with vertices and trances each vertex
1030 for ( anExp.ReInit() ; anExp.More(); anExp.Next() ) {
1031 TopoDS_Shape aVertex = anExp.Current();
1032 if ( aVertex.ShapeType() != TopAbs_VERTEX )
1033 continue;
1034 curNb++;
1035 transferVertex (FP, aGSS, aVertex, curNb);
1036 } // end of iteration on compound with vertices.
1037 aGCSet->SetElements(aGSS);
1038 item = aGCSet;
1039 } // end of check that number of vertices is not null
1040 }
1041 // PTV 22.08.2002 OCC609------------------------- end --------------------
1042 break;
1043 }
1044 default: break;
1045 }
1046 if ( item.IsNull() ) continue;
1047
1048 // add resulting item to the FP
1049 ItemSeq->Append(item);
1050 Handle(TransferBRep_ShapeMapper) submapper;
1051 if ( xShape.IsSame ( mapper->Value() ) )
1052 submapper = Handle(TransferBRep_ShapeMapper)::DownCast ( start );
1053 if ( submapper.IsNull() ) submapper = TransferBRep::ShapeMapper (FP,xShape);
1054 Handle(Transfer_Binder) subbind = FP->Find ( submapper );
1055 if ( subbind.IsNull() ) {
1056 subbind = TransientResult ( item );
1057 FP->Bind ( submapper, subbind );
1058 }
1059 else subbind->AddResult ( TransientResult ( item ) );
1060
1061 //:abv 24Jan99 CAX-IF TRJ3: Update FinderProcess map to take into account shape processing
1062// UpdateMap ( xShape, CSMT, DMT, FP );
1063 XSAlgo::AlgoContainer()->MergeTransferInfo(FP, info);
1064 }
1065
1066 // - Make Shape Representation
1067 Standard_Integer nCc1 = ItemSeq->Length();
1068 if (nCc1 < 1) {
1069 FP->AddFail(start,"The Shape has not the appropriate type");
1070 return binder;
1071 }
1072 Handle(StepShape_ShapeRepresentation) shapeRep;
1073 if ( theShape.ShapeType() == TopAbs_SHAPE ) { // for external references
1074 shapeRep = new StepShape_ShapeRepresentation;
1075 }
1076 else {
1077 switch (mymode) {
1078 case STEPControl_ManifoldSolidBrep:
1079 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1080 break;
1081 case STEPControl_FacetedBrep:
1082 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1083 break;
1084 // NOTE: STEPControl_AsIs mode is normally used to transfer non-manifold topology.
1085 // However, as ShellBasedSurfaceModel is used in non-manifold processing
1086 // internally, STEPControl_ShellBasedSurfaceModel is also adjusted to
1087 // be able to work with non-manifold cases
1088 case STEPControl_ShellBasedSurfaceModel:
1089 if (isManifold)
1090 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1091 else {
1092 Standard_Boolean isNewNMSSRCreated;
1093 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1094 useExistingNMSSR = !isNewNMSSRCreated;
1095 }
1096 break;
1097 case STEPControl_GeometricCurveSet:
1098 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1099 break;
1100 case STEPControl_AsIs :
1101 {
1102 if(nbs == 1) {
1103 if(trmode == STEPControl_ManifoldSolidBrep)
1104 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1105 else if(trmode == STEPControl_ShellBasedSurfaceModel)
1106 // Process non-manifold topology separately (ssv; 13.11.2010)
1107 if (isManifold)
1108 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1109 else {
1110 Standard_Boolean isNewNMSSRCreated;
1111 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1112 useExistingNMSSR = !isNewNMSSRCreated;
1113 }
1114 else if(trmode == STEPControl_GeometricCurveSet)
1115 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1116 else if(trmode ==STEPControl_FacetedBrep)
1117 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1118 }
1119 else shapeRep = new StepShape_ShapeRepresentation;
1120 }
1121 break;
1122 default: break;
1123 }
1124 }
1125 if(shapeRep.IsNull()) {
1126 Handle(Transfer_Binder) resb;
1127 return resb;
1128 }
1129
1130 Handle(StepRepr_HArray1OfRepresentationItem) items =
1131 new StepRepr_HArray1OfRepresentationItem(1,nCc1);
1132
1133 for (Standard_Integer rep = 1; rep <= nCc1; rep++) {
1134 Handle(StepRepr_RepresentationItem) repit =
1135 GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep));
1136 items->SetValue(rep,repit);
1137 }
1138 Standard_Integer ap = Interface_Static::IVal("write.step.schema");
1139 Transfer_SequenceOfBinder aSeqBindRelation;
1140 if(ap == 3 && nbs > 1) {
1141 Standard_Integer j = 1;
1142 if(items->Value(j)->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d))) {
1143 Handle(StepRepr_HArray1OfRepresentationItem) axis =
1144 new StepRepr_HArray1OfRepresentationItem(1,1);
1145 axis->SetValue(1,items->Value(j++));
1146 shapeRep->SetItems(axis);
1147 }
1148 for (; j <= items->Length(); j++) {
1149
1150 Handle(StepShape_ShapeRepresentation) ShapeRepr1;
1151 if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep)))
1152 ShapeRepr1 = new StepShape_AdvancedBrepShapeRepresentation;
1153 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel)))
1154 ShapeRepr1 = new StepShape_ManifoldSurfaceShapeRepresentation;
1155 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_GeometricCurveSet)))
1156 ShapeRepr1 = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1157 else if (items->Value(j)->IsKind(STANDARD_TYPE(StepShape_FacetedBrep)))
1158 ShapeRepr1 = new StepShape_FacetedBrepShapeRepresentation;
1159 else ShapeRepr1 = new StepShape_ShapeRepresentation;
1160
1161 Handle(StepRepr_HArray1OfRepresentationItem) repr1 = new StepRepr_HArray1OfRepresentationItem(1,2);
1162 repr1->SetValue(1,myContext.GetDefaultAxis());
1163 repr1->SetValue(2,items->Value(j));
1164 ShapeRepr1->SetItems(repr1);
1165 STEPConstruct_UnitContext mk1;
1166 mk1.Init(Tol);
1167 ShapeRepr1->SetContextOfItems(mk1.Value()); // la tolerance, voir au debut
1168 ShapeRepr1->SetName (new TCollection_HAsciiString(""));
1169
1170 Handle(StepRepr_ShapeRepresentationRelationship) aShapeRel = new StepRepr_ShapeRepresentationRelationship;
1171 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
1172 Handle(TCollection_HAsciiString) aDescr = new TCollection_HAsciiString("");
1173 aShapeRel->SetName(aName);
1174 aShapeRel->SetDescription(aDescr);
1175 aShapeRel->SetRep2(shapeRep);
1176 aShapeRel->SetRep1(ShapeRepr1);
1177
1178 aSeqBindRelation.Append(TransientResult (aShapeRel));
1179 }
1180 }
1181 else {
1182 if (!useExistingNMSSR)
1183 shapeRep->SetItems(items);
1184 else {
1185 // Add new representation item to the NMSSR's existing collection (ssv; 13.11.2010)
1186 Handle(StepRepr_HArray1OfRepresentationItem) oldItems = shapeRep->Items();
1187 Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1188 new StepRepr_HArray1OfRepresentationItem(1, oldItems->Length() + 1);
1189 Standard_Integer el = 1;
1190 for (Standard_Integer i = 1; i <= oldItems->Length(); i++)
1191 newItems->SetValue( el++, oldItems->Value(i) );
1192 newItems->SetValue( el, items->Value( items->Length() ) );
1193 shapeRep->SetItems(newItems);
1194 }
1195 }
1196
1197 // init representation
1198 STEPConstruct_UnitContext mk;
1199 mk.Init(Tol);
1200 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1201 shapeRep->SetName (new TCollection_HAsciiString(""));
1202
1203 // Create SDR (only once for non-manifold group)
1204 if (!useExistingNMSSR) {
1205 SDR0->SetUsedRepresentation (shapeRep);
1206 // create binder for SR and attach to it binder for RepItem (if exists)
1207 Handle(Transfer_Binder) resbind = TransientResult(shapeRep);
1208 binder = FP->Find(start);
1209 if ( ! binder.IsNull() ) {
1210 resbind->AddResult ( binder );
1211 FP->Rebind(start,resbind);
1212 //binder->AddResult ( resbind );
1213 //resbind = binder;
1214 }
1215 for(Standard_Integer k = 1; k <= aSeqBindRelation.Length(); k++)
1216 resbind->AddResult(aSeqBindRelation.Value(k));
1217
1218 // Add SDR for non-manifold topology in group mode 0 (ssv; 18.11.2010)
1219 if ( !aNMBinder.IsNull() )
1220 resbind->AddResult(aNMBinder);
1221
1222 return resbind;
1223 } else return FP->Find(start);
1224
1225}
1226
1227//=======================================================================
1228//function : TransferCompound
1229// #### TRANSFER COMPOUND AS (SUB-)ASSEMBLY
1230//purpose :
1231//=======================================================================
1232
1233Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(Transfer_Finder)& start,
1234 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1235 const Handle(Transfer_FinderProcess)& FP)
1236{
1237 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1238 Handle(Transfer_Binder) binder;
1239 if (mapper.IsNull()) return binder;
1240 TopoDS_Shape theShape = mapper->Value();
1241
1242 // Inspect non-manifold topology case (ssv; 10.11.2010)
1243 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
1244 Standard_Boolean isManifold;
1245 if (isNMMode)
1246 isManifold = IsManifoldShape(theShape);
1247 else
1248 isManifold = Standard_True;
1249
1250 // get a sequence of components (subshapes)
1251 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
1252 // Prepare a collection for non-manifold group of shapes
1253 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
1254 // PTV OCC725 17.09.2002 -- begin --
1255 Standard_Integer nbFreeVrtx = 0;
1256 TopoDS_Compound aCompOfVrtx;
1257 BRep_Builder aB;
1258 aB.MakeCompound(aCompOfVrtx);
1259
1260 #ifdef DEB
1261 if (!isManifold)
1262 cout << "Exploding Solids to Shells if any..." << endl;
1263 #endif
1264
1265 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1266 TopoDS_Shape aSubShape = iter.Value();
1267 if (aSubShape.ShapeType() != TopAbs_VERTEX) {
1268
1269 // Store non-manifold topology as shells (ssv; 10.11.2010)
1270 if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
1271 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
1272 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
1273 aSubShell.Closed(Standard_True);
1274 RepItemSeq->Append(aSubShell);
1275 NonManifoldGroup->Append(aSubShell);
1276 }
1277 }
1278 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
1279 RepItemSeq->Append(aSubShape);
1280 NonManifoldGroup->Append(aSubShape);
1281 }
1282 else
1283 RepItemSeq->Append(aSubShape);
1284
1285 continue;
1286 }
1287 aB.Add(aCompOfVrtx, iter.Value());
1288 nbFreeVrtx++;
1289 }
1290 if (nbFreeVrtx)
1291 RepItemSeq->Append (aCompOfVrtx);
1292
1293 // PTV OCC725 17.09.2002 -- end --
1294
1295 // Constitution : liste d axes, le premier est l origine, les suivants : 1
1296 // par sous-item
1297 Handle(StepShape_ShapeRepresentation) shapeRep =
1298 Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
1299 if ( shapeRep.IsNull() ) {
1300 shapeRep = new StepShape_ShapeRepresentation;
1301 SDR0->SetUsedRepresentation(shapeRep); // to be used by MakeItem
1302 }
1303 binder = TransientResult(SDR0); // set SDR as first item in order to be found first (but not SDR of subshape!)
1304 binder->AddResult ( TransientResult(shapeRep) );
1305
1306 // translate components
1307 Standard_Integer i, nbs = RepItemSeq->Length();
1308 Handle(TColStd_HSequenceOfTransient) ItemSeq = new TColStd_HSequenceOfTransient();
1309 ItemSeq->Append (myContext.GetDefaultAxis());
1310 myContext.NextLevel();
1311 for ( i = 1; i <= nbs; i ++) {
1312 Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper (FP,RepItemSeq->Value(i));
1313 Handle(StepGeom_Axis2Placement3d) AX1;
1314
1315 Handle(Transfer_Binder) bnd = TransferSubShape(subs, SDR0, AX1, FP, NonManifoldGroup, isManifold);
1316
1317 if (!AX1.IsNull()) ItemSeq->Append (AX1);
1318 // copy binders so as to have all roots in upper binder, but do not conflict
1319 while ( !bnd.IsNull() ) {
1320 Handle(Transfer_SimpleBinderOfTransient) bx =
1321 Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
1322 if ( !bx.IsNull() )
1323 // Single SDR is created for a non-manifold group (ssv: 12.11.2010)
1324 if (!isManifold && i > 1)
1325 break;
1326 else
1327 binder->AddResult( TransientResult( bx->Result() ) );
1328 bnd = bnd->NextResult();
1329 }
1330 }
1331 myContext.PrevLevel();
1332
1333 Standard_Integer nsub = ItemSeq->Length();
1334 Handle(StepRepr_HArray1OfRepresentationItem) items =
1335 new StepRepr_HArray1OfRepresentationItem(1,nsub);
1336
1337 // initialize representation
1338 for (Standard_Integer rep = 1; rep <= nsub; rep++)
1339 items->SetValue(rep,GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep)));
1340 shapeRep->SetItems(items);
1341 Standard_Real Tol = UsedTolerance (mytoler,theShape);
1342 STEPConstruct_UnitContext mk;
1343 mk.Init(Tol);
1344 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1345 shapeRep->SetName (new TCollection_HAsciiString(""));
1346
1347 // set it to SDR
1348// SDR0->SetUsedRepresentation (shapeRep);
1349
1350 return binder;
1351}
1352
1353//=======================================================================
1354//function : TransferSubShape
1355//purpose :
1356//=======================================================================
1357
1358Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape (const Handle(Transfer_Finder)& start,
1359 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1360 Handle(StepGeom_Axis2Placement3d)& AX1,
1361 const Handle(Transfer_FinderProcess)& FP,
1362 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
1363 const Standard_Boolean isManifold)
1364{
1365 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1366 if (mapper.IsNull()) return NullResult();
1367 TopoDS_Shape shape = mapper->Value();
1368
1369 // SHAPE EN POSITION VENANT D UN ASSEMBLAGE
1370 // Il faut alors distinguer la transformation de la shape meme
1371 // laquelle est consideree a l origine, puis transferee
1372 // A part, un item decrivant une occurence en position est cree
1373 // SINON, la shape est prise et transferee telle quelle
1374 TopoDS_Shape sh0 = shape;
1375 gp_Trsf aLoc;
1376 if ( GroupMode() >0) {
1377 TopLoc_Location shloc = shape.Location();
1378 aLoc = shloc.Transformation();
1379 TopLoc_Location shident;
1380 sh0.Location (shident);
1381 mapper = TransferBRep::ShapeMapper(FP,sh0);
1382 mapper->SameAttributes (start);
1383 }
1384
1385 Handle(Transfer_Binder) resbind = FP->Find(mapper);
1386 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
1387// Handle(StepShape_ShapeRepresentation) resultat;
1388 STEPConstruct_Part SDRTool;
1389
1390 // Already SDR and SR available : take them as are
1391 Standard_Boolean iasdr = FP->GetTypedTransient
1392 (resbind,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation),sdr);
1393 if ( iasdr ) SDRTool.ReadSDR ( sdr );
1394 else {
1395 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
1396 sdr = SDRTool.SDRValue();
1397 }
1398// resultat = GetCasted(StepShape_ShapeRepresentation,sdr->UsedRepresentation());
1399
1400 // if shape itself not yet translated, do it now
1401 //:abv 20.05.02: see comment in TransferShape(): added "! iasdr ||"
1402 Handle(Transfer_Binder) resprod = TransientResult(sdr); //KA - OCC7141(skl 10.11.2004)
1403 if ( ! iasdr || resbind.IsNull() ) {
1404 resbind = TransferShape(mapper, sdr, FP, shapeGroup, isManifold);
1405 Handle(Transfer_Binder) oldbind = FP->Find ( mapper );
1406 if ( ! oldbind.IsNull() && !resbind.IsNull()) resbind->AddResult ( oldbind );
1407 FP->Bind (mapper,resbind);
1408 resprod=resbind; //KA - OCC7141(skl 10.11.2004)
1409 }
1410
1411 // A new resbind may have been produced
1412// DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);
1413// if (restrans.IsNull()) return resbind;
1414// FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
1415// sdr->SetUsedRepresentation(resultat); // to be used by MakeItem
1416
1417 // make location for assembly placement
1418 GeomToStep_MakeAxis2Placement3d mkax (aLoc);
1419 Handle(StepGeom_Axis2Placement3d) AxLoc = mkax.Value();
1420 AX1 = AxLoc;
1421
1422 // create assembly structures (CDSR, NAUO etc.)
1423 STEPConstruct_Assembly mkitem;
1424 mkitem.Init (sdr,SDR0,myContext.GetDefaultAxis(),AxLoc);
1425 mkitem.MakeRelationship ();
1426 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink ( mkitem );
1427
1428 // add roots corresponding to assembly and product structures to binder
1429 //Handle(Transfer_Binder) resprod = resbind; //KA - OCC7141(skl 10.11.2004)
1430 //KA: we need only the current subshape in resprod, since the binder is copied
1431 // in Transfershape which calls Transfersubshape [ OCC7141(skl 10.11.2004) ]
1432 if ( ! iasdr ) {
1433 resprod->AddResult ( TransientResult ( SDRTool.SDRValue() ) );
1434 resbind->AddResult ( TransientResult ( SDRTool.SDRValue() ) ); //KA - OCC7141(skl 10.11.2004)
1435 roots->Append ( myContext.GetRootsForPart ( SDRTool ) );
1436 }
1437 for ( Standard_Integer i=1; i <= roots->Length(); i++ ) {
1438 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
1439 resbind->AddResult ( TransientResult ( roots->Value(i) ) ); //KA - OCC7141(skl 10.11.2004)
1440 }
1441 myContext.NextIndex();
1442
1443 //FP->Bind (mapper,resprod); //KA - OCC7141(skl 10.11.2004)
1444
1445 // abv 16.10.00: bind CDSR (et al) to located shape in order to be able to track instances
1446 if ( mapper != start ) {
1447 Handle(Transfer_Binder) bnd = FP->Find ( start );
1448 for ( Standard_Integer j=1; j <= roots->Length(); j++ )
1449 if ( bnd.IsNull() ) bnd = TransientResult ( roots->Value(j) );
1450 else bnd->AddResult ( TransientResult ( roots->Value(j) ) );
1451 FP->Bind ( start, bnd );
1452 }
1453
1454 return resprod;
1455}