0031007: Coding - eliminate warnings issued while compiling with -pedantic flag
[occt.git] / src / STEPConstruct / STEPConstruct_ValidationProps.cxx
1 // Created on: 1999-09-09
2 // Created by: Andrey BETENEV
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <APIHeaderSection_MakeHeader.hxx>
19 #include <gp_Pnt.hxx>
20 #include <Interface_EntityIterator.hxx>
21 #include <Interface_Macros.hxx>
22 #include <Interface_Static.hxx>
23 #include <Message.hxx>
24 #include <Message_Messenger.hxx>
25 #include <StepBasic_DerivedUnit.hxx>
26 #include <StepBasic_DerivedUnitElement.hxx>
27 #include <StepBasic_HArray1OfDerivedUnitElement.hxx>
28 #include <StepBasic_MeasureValueMember.hxx>
29 #include <StepBasic_MeasureWithUnit.hxx>
30 #include <StepBasic_ProductDefinition.hxx>
31 #include <StepBasic_SiUnitAndAreaUnit.hxx>
32 #include <StepBasic_SiUnitAndLengthUnit.hxx>
33 #include <StepBasic_Unit.hxx>
34 #include <STEPConstruct.hxx>
35 #include <STEPConstruct_UnitContext.hxx>
36 #include <STEPConstruct_ValidationProps.hxx>
37 #include <StepData_StepModel.hxx>
38 #include <StepGeom_CartesianPoint.hxx>
39 #include <StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext.hxx>
40 #include <StepGeom_GeometricRepresentationItem.hxx>
41 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
42 #include <StepRepr_CharacterizedDefinition.hxx>
43 #include <StepRepr_GlobalUnitAssignedContext.hxx>
44 #include <StepRepr_HArray1OfRepresentationItem.hxx>
45 #include <StepRepr_MeasureRepresentationItem.hxx>
46 #include <StepRepr_NextAssemblyUsageOccurrence.hxx>
47 #include <StepRepr_ProductDefinitionShape.hxx>
48 #include <StepRepr_PropertyDefinition.hxx>
49 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
50 #include <StepRepr_RepresentationContext.hxx>
51 #include <StepRepr_RepresentationItem.hxx>
52 #include <StepRepr_RepresentationRelationship.hxx>
53 #include <StepRepr_ShapeAspect.hxx>
54 #include <StepRepr_ShapeRepresentationRelationship.hxx>
55 #include <StepShape_ContextDependentShapeRepresentation.hxx>
56 #include <StepShape_ShapeDefinitionRepresentation.hxx>
57 #include <StepShape_ShapeRepresentation.hxx>
58 #include <TCollection_HAsciiString.hxx>
59 #include <TopLoc_Location.hxx>
60 #include <TopoDS_Iterator.hxx>
61 #include <TopoDS_Shape.hxx>
62 #include <Transfer_Binder.hxx>
63 #include <Transfer_SimpleBinderOfTransient.hxx>
64 #include <TransferBRep.hxx>
65 #include <TransferBRep_ShapeMapper.hxx>
66 #include <XSControl_TransferReader.hxx>
67 #include <XSControl_TransferWriter.hxx>
68 #include <XSControl_WorkSession.hxx>
69
70 //=======================================================================
71 //function : STEPConstruct_ValidationProps
72 //purpose  : 
73 //=======================================================================
74 STEPConstruct_ValidationProps::STEPConstruct_ValidationProps () 
75 {
76 }
77      
78 //=======================================================================
79 //function : STEPConstruct_ValidationProps
80 //purpose  : 
81 //=======================================================================
82
83 STEPConstruct_ValidationProps::STEPConstruct_ValidationProps (const Handle(XSControl_WorkSession) &WS)
84      : STEPConstruct_Tool(WS)
85 {
86 }
87
88 //=======================================================================
89 //function : Init
90 //purpose  : 
91 //=======================================================================
92
93 Standard_Boolean STEPConstruct_ValidationProps::Init (const Handle(XSControl_WorkSession) &WS)
94 {
95   return SetWS ( WS );
96 }
97
98 //=======================================================================
99 //function : TransientResult   CORRECTED
100 //purpose  : 
101 //=======================================================================
102
103 static Handle(Transfer_SimpleBinderOfTransient) TransientResult (const Handle(Standard_Transient)& res)
104 {
105   Handle(Transfer_SimpleBinderOfTransient) binder;
106   if (res.IsNull()) return binder;
107   binder = new Transfer_SimpleBinderOfTransient;
108   binder->SetResult (res);
109   return binder;
110 }
111
112 //=======================================================================
113 //function : FindTarget
114 //purpose  : 
115 //=======================================================================
116
117 Standard_Boolean STEPConstruct_ValidationProps::FindTarget (const TopoDS_Shape &Shape,
118                                                             StepRepr_CharacterizedDefinition &target,
119                                                             Handle(StepRepr_RepresentationContext) &Context,
120                                                             const Standard_Boolean instance)
121 {
122   // find the target STEP entity corresponding to a shape
123   Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess(), Shape );
124   Handle(Transfer_Binder) binder = FinderProcess()->Find ( mapper );
125   
126   // if requested, try to find instance of assembly
127   if ( instance ) {
128 /*
129     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO;
130     Standard_Boolean found = myAssemblyPD.IsNull()?
131       FinderProcess()->FindTypedTransient (mapper,STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence), NAUO) :
132          STEPConstruct::FindNAUO (binder,myAssemblyPD,NAUO);
133     if ( found ) {
134       //skl find CDSR using NAUO:
135       Handle(StepShape_ContextDependentShapeRepresentation) CDSR
136       Interface_EntityIterator subs1 = graph.Sharings(NAUO);
137       for (subs1.Start(); subs1.More(); subs1.Next()) {
138         Handle(StepRepr_ProductDefinitionShape) PDS = 
139           Handle(StepRepr_ProductDefinitionShape)::DownCast(subs1.Value());
140         if(PDS.IsNull()) continue;
141         //IsPDS=Standard_True;
142         Interface_EntityIterator subs2 = graph.Sharings(PDS);
143         for (subs2.Start(); CDSR.IsNull() && subs2.More(); subs2.Next()) {
144           CDSR = Handle(StepShape_ContextDependentShapeRepresentation)::DownCast(subs2.Value());
145         }
146       }
147       if(!CDSR.IsNull()) {
148         target.SetValue ( CDSR->RepresentedProductRelation() );
149         Context = CDSR->RepresentationRelation()->Rep2()->ContextOfItems();
150       }
151 #ifdef OCCT_DEBUG
152       else std::cout << "INSTANCE: CDRS from NAUO NOT found" << std::endl;
153 #endif
154     }
155 #ifdef OCCT_DEBUG
156     else std::cout << "INSTANCE: NAUO NOT found" << std::endl;
157 #endif
158 */
159   }
160
161   // for Compounds, search for SDR
162   else if ( Shape.ShapeType() == TopAbs_COMPOUND ) {
163     Handle(StepBasic_ProductDefinition) ProdDef;
164     if ( FinderProcess()->FindTypedTransient (mapper,STANDARD_TYPE(StepBasic_ProductDefinition), ProdDef) ) {
165       Handle(StepRepr_ProductDefinitionShape) PDS;
166       Interface_EntityIterator subs1 = Graph().Sharings(ProdDef);
167       for (subs1.Start(); PDS.IsNull() && subs1.More(); subs1.Next()) {
168         PDS = Handle(StepRepr_ProductDefinitionShape)::DownCast(subs1.Value());
169       }
170       target.SetValue ( PDS );
171 #ifdef OCCT_DEBUG
172 //      std::cout << "COMPOUND: SDR found: " << sdr->DynamicType()->Name() << std::endl;
173 #endif
174     }
175     else {
176 #ifdef OCCT_DEBUG
177       std::cout << "COMPOUND: ProdDef NOT found" << std::endl;
178 #endif
179       Handle(StepShape_ShapeRepresentation) SR;
180       if(FinderProcess()->FindTypedTransient(mapper,STANDARD_TYPE(StepShape_ShapeRepresentation),SR)) {
181         Handle(StepRepr_ProductDefinitionShape) PDS;
182         Interface_EntityIterator subs1 = Graph().Sharings(SR);
183         for (subs1.Start(); PDS.IsNull() && subs1.More(); subs1.Next()) {
184           Handle(StepShape_ShapeDefinitionRepresentation) SDR =
185             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs1.Value());
186           if(SDR.IsNull()) continue;
187           PDS = Handle(StepRepr_ProductDefinitionShape)::DownCast(SDR->Definition().PropertyDefinition());
188         }
189         if(PDS.IsNull()) {
190           subs1 = Graph().Sharings(SR);
191           for (subs1.Start(); PDS.IsNull() && subs1.More(); subs1.Next()) {
192             Handle(StepRepr_RepresentationRelationship) RR =
193               Handle(StepRepr_RepresentationRelationship)::DownCast(subs1.Value());
194             if(RR.IsNull()) continue;
195             Handle(StepShape_ShapeRepresentation) SR1;
196             if(RR->Rep1()==SR)
197               SR1 = Handle(StepShape_ShapeRepresentation)::DownCast(RR->Rep2());
198             else SR1 = Handle(StepShape_ShapeRepresentation)::DownCast(RR->Rep1());
199             if(!SR1.IsNull()) {
200               Interface_EntityIterator subs2 = Graph().Sharings(SR1);
201               for (subs2.Start(); PDS.IsNull() && subs2.More(); subs2.Next()) {
202                 Handle(StepShape_ShapeDefinitionRepresentation) SDR =
203                   Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs2.Value());
204                 if(SDR.IsNull()) continue;
205                 PDS = Handle(StepRepr_ProductDefinitionShape)::DownCast(SDR->Definition().PropertyDefinition());
206               }
207             }
208           }
209         }
210         if(!PDS.IsNull()) {
211           target.SetValue(PDS);
212           Context = SR->ContextOfItems();
213         }
214       }
215     }
216   }
217
218   // for others, search for GEOMETRIC_REPRESENTATION_ITEM
219   else {
220     Handle(StepGeom_GeometricRepresentationItem) item;
221     if ( FinderProcess()->FindTypedTransient (mapper,STANDARD_TYPE(StepGeom_GeometricRepresentationItem), item) ) {
222 #ifdef OCCT_DEBUG
223 //      std::cout << Shape.TShape()->DynamicType()->Name() << ": GeomRepItem found: " << item->DynamicType()->Name() << std::endl;
224 #endif
225       // find PDS (GRI <- SR <- SDR -> PDS)
226       Handle(StepRepr_ProductDefinitionShape) PDS;
227       Interface_EntityIterator subs = Graph().Sharings(item);
228       for (subs.Start(); PDS.IsNull() && subs.More(); subs.Next()) {
229 #ifdef OCCT_DEBUG
230 //      std::cout << "Parsing back refs: found " << subs.Value()->DynamicType()->Name() << std::endl;
231 #endif
232         if ( ! subs.Value()->IsKind(STANDARD_TYPE(StepShape_ShapeRepresentation)) ) continue;
233         Handle(StepShape_ShapeRepresentation) sr = 
234           Handle(StepShape_ShapeRepresentation)::DownCast ( subs.Value() );
235         Context = sr->ContextOfItems();
236         Interface_EntityIterator sub2 = Graph().Sharings(subs.Value());
237         for (sub2.Start(); sub2.More(); sub2.Next()) {
238           if ( ! sub2.Value()->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation)) ) continue;
239           Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
240             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(sub2.Value());
241           PDS = Handle(StepRepr_ProductDefinitionShape)::DownCast ( sdr->Definition().PropertyDefinition() );
242         }
243       }
244       if ( ! PDS.IsNull() ) {
245         // find SHAPE_ASPECT or create it with all associated info if not yet exists
246         Handle(StepRepr_ShapeAspect) aspect;
247         Handle(Transfer_Binder) bbb = binder;
248         while ( ! bbb.IsNull() ) {
249           Handle(Transfer_SimpleBinderOfTransient) bx = 
250             Handle(Transfer_SimpleBinderOfTransient)::DownCast ( bbb );
251           if ( ! bx.IsNull() ) {
252             Handle(StepRepr_ShapeAspect) asp = 
253               Handle(StepRepr_ShapeAspect)::DownCast ( bx->Result() );
254             if ( ! asp.IsNull() && asp->OfShape() == PDS ) {
255               aspect = asp;
256               break;
257             }
258           }
259           bbb = bbb->NextResult();
260         }
261         if ( aspect.IsNull() ) {
262 //      if ( ! FinderProcess()->FindTypedTransient (mapper,STANDARD_TYPE(StepRepr_ShapeAspect), aspect ) ||
263 //           aspect->OfShape() != PDS )
264 #ifdef OCCT_DEBUG
265           std::cout << Shape.TShape()->DynamicType()->Name() << ": SHAPE_ASPECT NOT found, creating" << std::endl;
266 #endif
267           // create aspect and all related data
268           Handle(TCollection_HAsciiString) AspectName = new TCollection_HAsciiString ( "" );
269           Handle(TCollection_HAsciiString) AspectDescr = new TCollection_HAsciiString ( "" );
270           aspect = new StepRepr_ShapeAspect;
271           aspect->Init ( AspectName, AspectDescr, PDS, StepData_LFalse );
272                         
273           StepRepr_CharacterizedDefinition SA;
274           SA.SetValue ( aspect );
275           
276           Handle(TCollection_HAsciiString) PropDefName = 
277             new TCollection_HAsciiString ( "shape with specific properties" );
278           Handle(TCollection_HAsciiString) PropDefDescr = new TCollection_HAsciiString ( "properties for subshape" );
279           Handle(StepRepr_PropertyDefinition) propdef = new StepRepr_PropertyDefinition;
280           propdef->Init ( PropDefName, Standard_True, PropDefDescr, SA );
281                   
282           Handle(TCollection_HAsciiString) SRName = new TCollection_HAsciiString ( "" );
283           Handle(StepShape_ShapeRepresentation) SR = new StepShape_ShapeRepresentation;
284           Handle(StepRepr_HArray1OfRepresentationItem) SRItems = new StepRepr_HArray1OfRepresentationItem ( 1, 1 );
285           SRItems->SetValue ( 1, item );
286           SR->Init ( SRName, SRItems, Context );
287           
288           Handle(StepShape_ShapeDefinitionRepresentation) SDR = new StepShape_ShapeDefinitionRepresentation;
289           StepRepr_RepresentedDefinition RD;
290           RD.SetValue ( propdef );
291           SDR->Init ( RD, SR );
292           
293           // record SHAPE_ASPECT in the map
294           binder->AddResult ( TransientResult ( aspect ) );
295
296           // add SDR and all the data into model
297           Model()->AddWithRefs ( SDR );
298         }
299         // SHAPE_ASPECT found, but we also need context: FIND IT !!!!
300         else { 
301 #ifdef OCCT_DEBUG
302           std::cout << Shape.TShape()->DynamicType()->Name() << ": SHAPE_ASPECT found" << std::endl;
303 #endif
304           Handle(StepRepr_ProductDefinitionShape) aPDS = aspect->OfShape();
305           Interface_EntityIterator asubs = Graph().Sharings(aPDS);
306           for (asubs.Start(); Context.IsNull() && asubs.More(); asubs.Next()) {
307             if ( ! asubs.Value()->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation)) ) continue;
308             Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
309               Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(asubs.Value());
310             Context = sdr->UsedRepresentation()->ContextOfItems();
311           }
312         }
313   
314         if ( ! aspect.IsNull() ) target.SetValue ( aspect );
315       }
316 #ifdef OCCT_DEBUG
317       else  std::cout << Shape.TShape()->DynamicType()->Name() << ": PDS NOT found, fail to create SHAPE_ASPECT" << std::endl;
318 #endif
319     }
320 #ifdef OCCT_DEBUG
321     else std::cout << Shape.TShape()->DynamicType()->Name() << ": GeomRepItem NOT found" << std::endl;
322 #endif
323   }
324
325   
326   // if target not found and shape has location, try the same shape without location
327   return ! target.IsNull();
328 }
329
330 //=======================================================================
331 //function : AddProp   CORRECTED
332 //purpose  : 
333 //=======================================================================
334
335 Standard_Boolean STEPConstruct_ValidationProps::AddProp (const StepRepr_CharacterizedDefinition &target,
336                                                          const Handle(StepRepr_RepresentationContext) &Context,
337                                                          const Handle(StepRepr_RepresentationItem) &Prop,
338                                                          const Standard_CString Descr)
339 {
340   // FINALLY, create a structure of 5 entities describing a link between a shape and its property
341   Handle(TCollection_HAsciiString) PropDefName = 
342     new TCollection_HAsciiString ( "geometric validation property" );
343   Handle(TCollection_HAsciiString) PropDefDescr = new TCollection_HAsciiString ( Descr );
344   Handle(StepRepr_PropertyDefinition) propdef = new StepRepr_PropertyDefinition;
345   propdef->Init ( PropDefName, Standard_True, PropDefDescr, target );
346                   
347   Handle(TCollection_HAsciiString) SRName = new TCollection_HAsciiString ( Descr );
348   Handle(StepRepr_Representation) rep = new StepRepr_Representation;
349   Handle(StepRepr_HArray1OfRepresentationItem) SRItems = new StepRepr_HArray1OfRepresentationItem ( 1, 1 );
350   SRItems->SetValue ( 1, Prop );
351   rep->Init ( SRName, SRItems, Context );
352           
353   Handle(StepRepr_PropertyDefinitionRepresentation) PrDR = new StepRepr_PropertyDefinitionRepresentation;
354   StepRepr_RepresentedDefinition RD;
355   RD.SetValue ( propdef );
356   PrDR->Init ( RD, rep );
357           
358   // record SDR in order to have it written to the file
359   Model()->AddWithRefs ( PrDR );
360
361   // for AP203, add subschema name
362   if ( Interface_Static::IVal("write.step.schema") ==3 ) {
363     APIHeaderSection_MakeHeader mkHdr ( Handle(StepData_StepModel)::DownCast ( Model() ) );
364     Handle(TCollection_HAsciiString) subSchema = 
365       new TCollection_HAsciiString ( "GEOMETRIC_VALIDATION_PROPERTIES_MIM" );
366     mkHdr.AddSchemaIdentifier ( subSchema );
367   }
368   
369   return Standard_True;
370 }
371
372 //=======================================================================
373 //function : AddProp   CORRECTED
374 //purpose  : 
375 //=======================================================================
376
377 Standard_Boolean STEPConstruct_ValidationProps::AddProp (const TopoDS_Shape &Shape,
378                                                          const Handle(StepRepr_RepresentationItem) &Prop,
379                                                          const Standard_CString Descr,
380                                                          const Standard_Boolean instance)
381 {
382   StepRepr_CharacterizedDefinition target;
383   Handle(StepRepr_RepresentationContext) Context;
384   if ( ! FindTarget ( Shape, target, Context, instance ) ) return Standard_False;
385   return AddProp ( target, Context, Prop, Descr );
386 }
387
388 //=======================================================================
389 //function : AddVolume   CORRECTED
390 //purpose  : 
391 //=======================================================================
392
393 Standard_Boolean STEPConstruct_ValidationProps::AddVolume (const TopoDS_Shape &Shape, 
394                                                            const Standard_Real Vol)
395 {
396   Handle(StepBasic_MeasureValueMember) Val = new StepBasic_MeasureValueMember;
397   Val->SetReal ( Vol );
398   //Val->SetName ( "solid volume" );
399   Val->SetName ( "VOLUME_MEASURE");
400
401   // for volume unit, either take existing or create a new
402   if ( volUnit.DerivedUnit().IsNull() ) {
403     Handle(StepBasic_SiUnitAndLengthUnit) MM = new StepBasic_SiUnitAndLengthUnit;
404     MM->Init ( Standard_True, StepBasic_spMilli, StepBasic_sunMetre );
405   
406     Handle(StepBasic_DerivedUnitElement) DUE = new StepBasic_DerivedUnitElement;
407     DUE->Init ( MM, 3. );
408   
409     Handle(StepBasic_HArray1OfDerivedUnitElement) DUElems = 
410       new StepBasic_HArray1OfDerivedUnitElement ( 1, 1 );
411     DUElems->SetValue ( 1, DUE );
412
413     Handle(StepBasic_DerivedUnit) DU = new StepBasic_DerivedUnit;
414     DU->Init ( DUElems );
415
416     volUnit.SetValue ( DU );
417   }
418   
419   Handle(TCollection_HAsciiString) MRIName = new TCollection_HAsciiString ( "volume measure" );
420   Handle(StepRepr_MeasureRepresentationItem) MRI = new StepRepr_MeasureRepresentationItem;
421   MRI->Init ( MRIName, Val, volUnit );
422   
423   return AddProp ( Shape, MRI, "volume" );
424 }
425
426 //=======================================================================
427 //function : AddArea   CORRECTED
428 //purpose  : 
429 //=======================================================================
430
431 Standard_Boolean STEPConstruct_ValidationProps::AddArea (const TopoDS_Shape &Shape, 
432                                                          const Standard_Real Area)
433 {
434   Handle(StepBasic_MeasureValueMember) Val = new StepBasic_MeasureValueMember;
435   Val->SetReal ( Area );
436   //Val->SetName ( "surface area" );
437   Val->SetName ( "AREA_MEASURE" );
438
439   // for area unit, either take existing or create a new
440   if ( areaUnit.DerivedUnit().IsNull() ) {
441     Handle(StepBasic_SiUnitAndLengthUnit) MM = new StepBasic_SiUnitAndLengthUnit;
442     MM->Init ( Standard_True, StepBasic_spMilli, StepBasic_sunMetre );
443   
444     Handle(StepBasic_DerivedUnitElement) DUE = new StepBasic_DerivedUnitElement;
445     DUE->Init ( MM, 2. );
446   
447     Handle(StepBasic_HArray1OfDerivedUnitElement) DUElems = 
448       new StepBasic_HArray1OfDerivedUnitElement ( 1, 1 );
449     DUElems->SetValue ( 1, DUE );
450
451     Handle(StepBasic_DerivedUnit) DU = new StepBasic_DerivedUnit;
452     DU->Init ( DUElems );
453
454     areaUnit.SetValue ( DU );
455   }
456   
457   Handle(TCollection_HAsciiString) MRIName = new TCollection_HAsciiString ( "surface area measure" );
458   Handle(StepRepr_MeasureRepresentationItem) MRI = new StepRepr_MeasureRepresentationItem;
459   MRI->Init ( MRIName, Val, areaUnit );
460   
461   return AddProp ( Shape, MRI, "surface area" );
462 }
463
464 //=======================================================================
465 //function : AddCentroid   CORRECTED
466 //purpose  : 
467 //=======================================================================
468
469 Standard_Boolean STEPConstruct_ValidationProps::AddCentroid (const TopoDS_Shape &Shape, 
470                                                              const gp_Pnt &Pnt,
471                                                              const Standard_Boolean instance)
472 {
473   Handle(TCollection_HAsciiString) CPName = new TCollection_HAsciiString ( "centre point" );
474   Handle(StepGeom_CartesianPoint) CP = new StepGeom_CartesianPoint;
475   CP->Init3D ( CPName, Pnt.X(), Pnt.Y(), Pnt.Z() );
476   
477   return AddProp ( Shape, CP, "centroid", instance );
478 }
479
480 //=======================================================================
481 //function : LoadProps   CORRECTED
482 //purpose  : 
483 //=======================================================================
484
485 Standard_Boolean STEPConstruct_ValidationProps::LoadProps (TColStd_SequenceOfTransient &seq) const
486 {
487   // parse on PropertyDefinitionRepresentations
488   Standard_Integer nb = Model()->NbEntities();
489   Handle(Standard_Type) tPDR = STANDARD_TYPE(StepRepr_PropertyDefinitionRepresentation);
490   for (Standard_Integer i = 1; i <= nb; i ++) {
491     Handle(Standard_Transient) enti = Model()->Value(i);
492     if ( ! enti->IsKind (tPDR) ) continue;
493     
494     Handle(StepRepr_PropertyDefinitionRepresentation) PDR = 
495       Handle(StepRepr_PropertyDefinitionRepresentation)::DownCast ( enti );
496     
497     // Check that PDR is for validation props.
498     Handle(StepRepr_PropertyDefinition) PD = PDR->Definition().PropertyDefinition();
499     if (!PD.IsNull() && !PD->Name().IsNull())
500     {
501       // Note: according to "Recommended Practices for Geometric and Assembly Validation Properties" Release 4.4
502       // as of Augist 17, 2016, item 4.6, the name of PropertyDefinition should be "geometric validation property"
503       // with words separated by spaces; however older versions of the same RP document used underscores.
504       // To be able to read files written using older convention, we convert all underscores to spaces for this check.
505       TCollection_AsciiString aName = PD->Name()->String();
506       aName.ChangeAll('_', ' ', Standard_False);
507       aName.LowerCase();
508       if (aName != "geometric validation property")
509         continue;
510     }
511
512     seq.Append ( PDR );
513   }
514   return seq.Length() >0;
515 }
516     
517 //=======================================================================
518 //function : GetPropPD   CORRECTED
519 //purpose  : 
520 //=======================================================================
521
522 Handle(StepBasic_ProductDefinition) STEPConstruct_ValidationProps::GetPropPD (const Handle(StepRepr_PropertyDefinition) &PD) const
523 {
524   StepRepr_CharacterizedDefinition CD = PD->Definition();
525     
526   // detect target entity of valprop
527   Handle(StepBasic_ProductDefinition) ProdDef;
528   Handle(StepRepr_PropertyDefinition) PDS = CD.ProductDefinitionShape();
529   if ( PDS.IsNull() ) {
530     Handle(StepRepr_ShapeAspect) SA = CD.ShapeAspect();
531     if ( SA.IsNull() ) {
532 #ifdef OCCT_DEBUG
533       Handle(Message_Messenger) sout = Message::DefaultMessenger();
534       sout << "Error: Cannot find target entity (SA) for geometric_validation_property "; 
535       Model()->PrintLabel ( PD, sout ); 
536       sout << Message_EndLine;
537 #endif
538       return ProdDef;
539     }
540     Interface_EntityIterator subs = Graph().Sharings(SA);
541     for (subs.Start(); subs.More(); subs.Next()) {
542       PDS = Handle(StepRepr_PropertyDefinition)::DownCast ( subs.Value() );
543       if ( PDS.IsNull() ) return ProdDef;
544       Interface_EntityIterator subs1 = Graph().Shareds(PDS);
545       for (subs1.Start(); ProdDef.IsNull() && subs1.More(); subs1.Next()) {
546         ProdDef = Handle(StepBasic_ProductDefinition)::DownCast ( subs1.Value() );
547       }
548     }
549   }
550   else {
551     Interface_EntityIterator subs = Graph().Shareds(PDS);
552     for (subs.Start(); ProdDef.IsNull() && subs.More(); subs.Next()) {
553       ProdDef = Handle(StepBasic_ProductDefinition)::DownCast ( subs.Value() );
554     }
555   }
556 #ifdef OCCT_DEBUG
557   if ( ProdDef.IsNull() ) {
558     Handle(Message_Messenger) sout = Message::DefaultMessenger();
559     sout << "Error: Cannot find target entity (SDR) for geometric_validation_property "; 
560     Model()->PrintLabel ( PD, sout ); 
561     sout << Message_EndLine;
562   }
563 #endif
564   return ProdDef;
565 }
566
567 //=======================================================================
568 //function : GetPropCDSR   CORRECTED
569 //purpose  : 
570 //=======================================================================
571
572 Handle(StepRepr_NextAssemblyUsageOccurrence) STEPConstruct_ValidationProps::GetPropNAUO (const Handle(StepRepr_PropertyDefinition) &PD) const
573 {
574   StepRepr_CharacterizedDefinition CD = PD->Definition();
575     
576   // detect target entity of valprop
577   Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO;
578   Handle(StepRepr_PropertyDefinition) PDS = CD.ProductDefinitionShape();
579   if ( PDS.IsNull() ) return NAUO; // not found
580   Interface_EntityIterator subs = Graph().Shareds(PDS);
581   for (subs.Start(); NAUO.IsNull() && subs.More(); subs.Next()) {
582     NAUO = Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast ( subs.Value() );
583   }
584   return NAUO;
585 }
586
587 //=======================================================================
588 //function : GetPropShape   CORRECTED
589 //purpose  : 
590 //=======================================================================
591
592 TopoDS_Shape STEPConstruct_ValidationProps::GetPropShape (const Handle(StepBasic_ProductDefinition) &ProdDef) const
593 {
594   // find target shape
595   TopoDS_Shape S;
596   Handle(Transfer_Binder) binder = TransientProcess()->Find(ProdDef);
597   if ( ! binder.IsNull() && binder->HasResult() ) {
598     S = TransferBRep::ShapeResult ( TransientProcess(), binder );
599   }
600   //if ( S.IsNull() ) { // for subshape (via shape_aspect)
601   //  Handle(StepRepr_Representation) rep = SDR->UsedRepresentation();
602   //  for ( Standard_Integer j=1; S.IsNull() && j <= rep->NbItems(); j++ ) {
603   //    binder = TransientProcess()->Find(rep->ItemsValue(j));
604   //    if ( ! binder.IsNull() && binder->HasResult() ) {
605   //    S = TransferBRep::ShapeResult ( TransientProcess(), binder );
606   //    }
607   //  }
608   //}
609 #ifdef OCCT_DEBUG
610   if ( S.IsNull() ) {
611     Handle(Message_Messenger) sout = Message::DefaultMessenger();
612     sout << "Warning: Entity "; 
613     Model()->PrintLabel ( ProdDef, sout ); 
614     sout << " is not mapped to shape" << Message_EndLine;
615   }
616 #endif
617   return S;
618 }
619     
620 //=======================================================================
621 //function : GetPropShape   CORRECTED
622 //purpose  : 
623 //=======================================================================
624
625 TopoDS_Shape STEPConstruct_ValidationProps::GetPropShape (const Handle(StepRepr_PropertyDefinition) &PD) const
626 {
627   Handle(StepBasic_ProductDefinition) ProdDef = GetPropPD ( PD );
628   TopoDS_Shape S;
629   if ( ! ProdDef.IsNull() ) S = GetPropShape ( ProdDef );
630   return S;
631 }
632
633 //=======================================================================
634 //function : GetPropReal
635 //purpose  : 
636 //=======================================================================
637
638 Standard_Boolean STEPConstruct_ValidationProps::GetPropReal (const Handle(StepRepr_RepresentationItem) &item,
639                                                              Standard_Real &Val, Standard_Boolean &isArea) const
640 {
641   // decode volume & area
642   if ( ! item->IsKind(STANDARD_TYPE(StepRepr_MeasureRepresentationItem)) ) 
643     return Standard_False;
644   
645   Handle(StepRepr_MeasureRepresentationItem) mri = 
646     Handle(StepRepr_MeasureRepresentationItem)::DownCast ( item );
647
648   Handle(StepBasic_MeasureWithUnit) M = mri->Measure();
649   TCollection_AsciiString Name = M->ValueComponentMember()->Name();
650   StepBasic_Unit Unit = M->UnitComponent();
651
652   Standard_Real scale = 1.;
653   Handle(StepBasic_DerivedUnit) DU = Unit.DerivedUnit();
654   if ( ! DU.IsNull() ) {
655     for(Standard_Integer ind = 1; ind <= DU->NbElements(); ind++) {
656       Handle(StepBasic_DerivedUnitElement) DUE = DU->ElementsValue(ind);
657       Standard_Real exp = DUE->Exponent();
658       Handle(StepBasic_NamedUnit) NU = DUE->Unit();
659       STEPConstruct_UnitContext unit;
660       unit.ComputeFactors(NU);
661       if(unit.LengthDone()) {
662         Standard_Real lengthFactor = unit.LengthFactor();
663         scale *= pow(lengthFactor,exp);
664       }
665     }
666   }
667   else {
668     Handle(StepBasic_NamedUnit) NU = Unit.NamedUnit();
669     if(!NU.IsNull()) {
670       STEPConstruct_UnitContext unit;
671       unit.ComputeFactors(NU);
672       if(unit.AreaDone())
673         scale =  unit.AreaFactor();
674       if(unit.VolumeDone())
675         scale =  unit.VolumeFactor();
676     }
677   }
678   
679   Val = M->ValueComponent() * scale;
680   
681   if ( Name == "AREA_MEASURE" ) isArea = Standard_True;
682   else if ( Name == "VOLUME_MEASURE" ) isArea = Standard_False; 
683   else {
684 #ifdef OCCT_DEBUG
685     std::cout << "Warning: Measure " << Model()->StringLabel ( M )->String() << " is neither area not volume" << std::endl;
686 #endif
687     return Standard_False;
688   }
689   return Standard_True;
690 }
691
692 //=======================================================================
693 //function : GetPropPnt
694 //purpose  : 
695 //=======================================================================
696
697 Standard_Boolean STEPConstruct_ValidationProps::GetPropPnt (const Handle(StepRepr_RepresentationItem) &item,
698                                                             const Handle(StepRepr_RepresentationContext) &Context,
699                                                             gp_Pnt &Pnt) const
700 {
701   // centroid
702   if ( ! item->IsKind(STANDARD_TYPE(StepGeom_CartesianPoint)) ) 
703     return Standard_False;
704   
705   Handle(StepGeom_CartesianPoint) P = Handle(StepGeom_CartesianPoint)::DownCast ( item );
706   if ( P.IsNull() || P->NbCoordinates() != 3 ) {
707 #ifdef OCCT_DEBUG
708     std::cout << "Warning: Point " << Model()->StringLabel ( P )->String() << " is not valid for centroid" << std::endl;
709 #endif
710     return Standard_False;
711   }
712
713   gp_Pnt pos ( P->CoordinatesValue(1), P->CoordinatesValue(2), P->CoordinatesValue(3) );
714         
715   // scale according to units
716   if ( ! Context.IsNull() ) {
717     Handle(StepRepr_GlobalUnitAssignedContext) theGUAC;
718     if (Context->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext))) {
719       DeclareAndCast(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext, theGRCAGAUC,Context);
720       theGUAC = theGRCAGAUC->GlobalUnitAssignedContext();
721     }
722     else if (Context->IsKind(STANDARD_TYPE(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx))) {
723       DeclareAndCast(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx,
724                      theGRCAGAUC,Context);
725       theGUAC = theGRCAGAUC->GlobalUnitAssignedContext();
726     }
727     if ( ! theGUAC.IsNull() ) {
728       STEPConstruct_UnitContext UnitTool;
729       UnitTool.ComputeFactors(theGUAC);
730       gp_Pnt zero(0,0,0);
731       pos.Scale ( zero, UnitTool.LengthFactor() );
732     }
733   }
734   Pnt = pos;
735
736   return Standard_True;
737 }
738
739 //=======================================================================
740 //function : SetAssemblyShape   CORRECTED
741 //purpose  : 
742 //=======================================================================
743
744 void STEPConstruct_ValidationProps::SetAssemblyShape (const TopoDS_Shape& shape)
745 {
746   Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper(FinderProcess(),shape);
747   FinderProcess()->FindTypedTransient(mapper,STANDARD_TYPE(StepBasic_ProductDefinition),myAssemblyPD);
748 }