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