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