0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / XDEDRAW / XDEDRAW_Props.cxx
1 // Created on: 2000-08-04
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 // OCC532 sln 24.07.2002. Add epsilon parameter to SetProps function
17
18 #include <BRep_Tool.hxx>
19 #include <BRepGProp.hxx>
20 #include <BRepMesh_IncrementalMesh.hxx>
21 #include <DBRep.hxx>
22 #include <DDocStd.hxx>
23 #include <Draw.hxx>
24 #include <gp_Pln.hxx>
25 #include <GProp_GProps.hxx>
26 #include <Poly_Triangulation.hxx>
27 #include <Precision.hxx>
28 #include <Standard_ErrorHandler.hxx>
29 #include <Standard_Failure.hxx>
30 #include <Standard_Stream.hxx>
31 #include <TColgp_Array1OfPnt.hxx>
32 #include <TColgp_Array1OfXYZ.hxx>
33 #include <TCollection_AsciiString.hxx>
34 #include <TCollection_HAsciiString.hxx>
35 #include <TColStd_Array1OfReal.hxx>
36 #include <TDataStd_Name.hxx>
37 #include <TDataStd_TreeNode.hxx>
38 #include <TDF_Label.hxx>
39 #include <TDF_LabelSequence.hxx>
40 #include <TDF_Tool.hxx>
41 #include <TDocStd_Document.hxx>
42 #include <TNaming_NamedShape.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopoDS.hxx>
45 #include <TopoDS_Compound.hxx>
46 #include <TopoDS_Face.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <XCAFDoc.hxx>
50 #include <XCAFDoc_Area.hxx>
51 #include <XCAFDoc_Centroid.hxx>
52 #include <XCAFDoc_DocumentTool.hxx>
53 #include <XCAFDoc_Location.hxx>
54 #include <XCAFDoc_MaterialTool.hxx>
55 #include <XCAFDoc_ShapeTool.hxx>
56 #include <XCAFDoc_Volume.hxx>
57 #include <XDEDRAW_Props.hxx>
58
59 #include <stdio.h>
60 // --------------------- VolumeFix Begin ---
61 //=======================================================================
62 //function : TetraVol
63 //purpose  : auxilary
64 //=======================================================================
65 static double TetraVol(gp_Pnt RefPoint, gp_Pnt Som1, gp_Pnt Som2, gp_Pnt Som3)
66 {
67   double curVolume = 0;
68   gp_Dir Line12;
69   gp_Pln Plane123;
70   gp_Vec N;
71   
72   {
73     try
74       {
75       OCC_CATCH_SIGNALS
76         Line12=gp_Dir( gp_Vec(Som1, Som2));
77         gp_Vec v1(Som1, Som2);
78         gp_Vec v2(Som2, Som3);
79         N=v1^v2;
80         Plane123=gp_Pln( Som1, gp_Dir( N ) );
81       }
82     catch(Standard_Failure const&) {return(0.);}
83   }
84   double L1, L2, L3;
85   L1 = Som1.Distance(Som2);
86   L2 = gp_Lin(Som1, Line12).Distance(Som3);
87   L3 = Plane123.Distance(RefPoint);
88   
89   curVolume = ((L1 * L2)/2) * (L3/3);
90   
91   gp_Vec Rad(RefPoint, Som1);
92   
93   if( (Rad*N)>0 )
94     return (curVolume);
95   else
96     return (-curVolume);
97 }
98
99
100 //=======================================================================
101 //function : TetraCen
102 //purpose  : auxilary
103 //=======================================================================
104 static gp_XYZ TetraCen(gp_Pnt RefPoint, gp_Pnt Som1, gp_Pnt Som2, gp_Pnt Som3)
105 {
106   gp_XYZ curCentr, plnPnt;
107   plnPnt = ( Som1.XYZ() + Som2.XYZ() + Som3.XYZ() )/3;
108   curCentr = plnPnt + (RefPoint.XYZ() - plnPnt)/4;
109   return curCentr;
110 }
111
112
113 //=======================================================================
114 //function : CalculVolume
115 //purpose  : auxilary
116 //=======================================================================
117 static Standard_Real CalculVolume(const TopoDS_Shape& So,
118                                   gp_Pnt&       aRefPoint,
119                                   Standard_Real       tol,
120                                   Standard_Boolean withForce,
121                                   Draw_Interpretor& di)
122 {
123   Standard_Real myVolume = 0, curVolume = 0;
124   gp_XYZ localCentroid(0,0,0), curCentroid(0,0,0);
125   Standard_Boolean haveVertex = Standard_False;
126   for (TopExp_Explorer ex(So,TopAbs_FACE) ; ex.More(); ex.Next())
127     {
128       TopoDS_Face F =TopoDS::Face(ex.Current());
129       TopLoc_Location L;
130       if ( ! haveVertex )
131         for (TopExp_Explorer Vex(F, TopAbs_VERTEX); Vex.More(); Vex.Next() )
132           {
133             TopoDS_Vertex v = TopoDS::Vertex(Vex.Current());
134             if ( ! v.IsNull() ) {
135               aRefPoint = BRep_Tool::Pnt(v);
136               haveVertex = Standard_True;
137               break;
138             }
139           }
140       
141       Handle (Poly_Triangulation) facing = BRep_Tool::Triangulation(F,L);
142       if(facing.IsNull() || withForce)
143         {
144           BRepMesh_IncrementalMesh MESH(F, tol);
145           
146           facing = BRep_Tool::Triangulation(F,L);
147         }
148
149       TColgp_Array1OfPnt tab(1,(facing->NbNodes()));
150       tab = facing->Nodes();
151       Poly_Array1OfTriangle tri(1,facing->NbTriangles());
152       tri = facing->Triangles();
153       for (Standard_Integer i=1;i<=(facing->NbTriangles());i++)
154         {
155           
156           Poly_Triangle trian = tri.Value(i);
157           Standard_Integer index1,index2,index3;//M,N;
158           if( F.Orientation() == TopAbs_REVERSED )
159             trian.Get(index1,index3,index2);
160           else
161             trian.Get(index1,index2,index3);
162           curVolume = TetraVol(aRefPoint, tab.Value(index1),
163                                tab.Value(index2), tab.Value(index3));
164           myVolume += curVolume;
165           curCentroid = TetraCen(aRefPoint, tab.Value(index1),
166                                  tab.Value(index2), tab.Value(index3));
167           
168           localCentroid = localCentroid + curCentroid*curVolume;
169         }
170     }
171   
172   localCentroid = localCentroid * (1./ myVolume);
173   
174   di << "Centroid:\n";
175   di << "X=\t" << localCentroid.X() << "\n";
176   di << "Y=\t" << localCentroid.Y() << "\n";
177   di << "Z=\t" << localCentroid.Z() << "\n";
178   return (myVolume);
179 }
180
181
182 // --------------------- VolumeFix End   ---
183
184
185 //=======================================================================
186 // Section: Work with val props
187 //=======================================================================
188
189 //=======================================================================
190 //function : SetProps
191 //purpose  : 
192 //=======================================================================
193
194 static Standard_Integer SetProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
195 {
196   if (argc < 3) {
197     di<<"Use: "<<argv[0]<<" DocName {Shape|Label} [epsilon = 0.001]\n";
198     return 1;
199   }
200   Handle(TDocStd_Document) Doc;
201   DDocStd::GetDocument(argv[1], Doc);
202   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
203   
204   Standard_Real Vres, Ares;
205
206   TDF_Label aLabel;
207   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
208   TopoDS_Shape aShape;
209   if ( aLabel.IsNull() ) {
210     aShape= DBRep::Get(argv[2]);
211     if ( !aShape.IsNull() ) {
212       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
213       aLabel = STool->FindShape(aShape);
214     }
215   }
216   else {
217     aShape = XCAFDoc_ShapeTool::GetShape ( aLabel );
218   }
219   if ( !aLabel.IsNull() ) {
220     
221     // retrieve epsilon
222     Standard_Real anEps;
223     if(argc > 3 ) anEps = Draw::Atof(argv[3]);
224     else anEps = 0.001;
225     
226     GProp_GProps G;
227     BRepGProp::VolumeProperties(aShape,G,anEps,Standard_True);
228     Vres = G.Mass();
229     Handle(XCAFDoc_Volume) aVolume = new XCAFDoc_Volume;
230     if (!aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume)) aLabel.AddAttribute(aVolume);
231     aVolume->Set(Vres);
232     
233     gp_Pnt aPoint = G.CentreOfMass();
234     Handle(XCAFDoc_Centroid) aCentroid = new XCAFDoc_Centroid;
235     if (!aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) aLabel.AddAttribute(aCentroid);
236     aCentroid->Set(aPoint);
237
238     BRepGProp::SurfaceProperties(aShape,G,anEps);
239     Ares = G.Mass();
240     Handle(XCAFDoc_Area) aArea = new XCAFDoc_Area;
241     if (!aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea)) aLabel.AddAttribute(aArea);
242     aArea->Set(Ares);
243     
244     di << argv[2] << ": Volume = " << Vres << ", Area = " << Ares << 
245       ", Centroid is (" << aPoint.X() << ", " << aPoint.Y() << ", " << aPoint.Z() << ")";
246   }
247   return 0;
248 }
249
250
251 //=======================================================================
252 //function : SetVolume
253 //purpose  : 
254 //=======================================================================
255
256 static Standard_Integer SetVolume (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
257 {
258   if (argc!=4) {
259     di<<"Use: "<<argv[0]<<" DocName {Label|Shape} volume\n";
260     return 1;
261   }
262   Handle(TDocStd_Document) Doc;
263   DDocStd::GetDocument(argv[1], Doc);
264   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
265   
266   Standard_Real res=0.;
267
268   TDF_Label aLabel;
269   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
270   if ( aLabel.IsNull() ) {
271     TopoDS_Shape aShape= DBRep::Get(argv[2]);
272     if ( !aShape.IsNull() ) {
273       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
274       aLabel = STool->FindShape(aShape);
275     }
276   }
277   if ( !aLabel.IsNull() ) {
278     res = Draw::Atof(argv[3]);
279     Handle(XCAFDoc_Volume) aVolume = new XCAFDoc_Volume;
280     if (!aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume)) aLabel.AddAttribute(aVolume);
281     aVolume->Set(res);
282   }
283   
284   di << res;
285   return 0;
286 }
287
288
289 //=======================================================================
290 //function : SetArea
291 //purpose  : 
292 //=======================================================================
293
294 static Standard_Integer SetArea (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
295 {
296   if (argc!=4) {
297     di<<"Use: "<<argv[0]<<" DocName {Label|Shape} area\n";
298     return 1;
299   }
300   Handle(TDocStd_Document) Doc;
301   DDocStd::GetDocument(argv[1], Doc);
302   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
303   
304   Standard_Real res=0.;
305
306   TDF_Label aLabel;
307   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
308   if ( aLabel.IsNull() ) {
309     TopoDS_Shape aShape= DBRep::Get(argv[2]);
310     if ( !aShape.IsNull() ) {
311       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
312       aLabel = STool->FindShape(aShape);
313     }
314   }
315   if ( !aLabel.IsNull() ) {
316     res = Draw::Atof(argv[3]);
317     Handle(XCAFDoc_Area) aArea = new XCAFDoc_Area;
318     if (!aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea)) aLabel.AddAttribute(aArea);
319     aArea->Set(res);
320   }
321   di << res;
322   return 0;
323 }
324
325
326 //=======================================================================
327 //function : SetCentroid
328 //purpose  : 
329 //=======================================================================
330
331 static Standard_Integer SetCentroid (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
332 {
333   if (argc!=6) {
334     di<<"Use: "<<argv[0]<<" DocName {Label|Shape} x y z\n";
335     return 1;
336   }
337   Handle(TDocStd_Document) Doc;
338   DDocStd::GetDocument(argv[1], Doc);
339   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
340   
341   gp_Pnt aPoint;
342
343   TDF_Label aLabel;
344   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
345   if ( aLabel.IsNull() ) {
346     TopoDS_Shape aShape= DBRep::Get(argv[2]);
347     if ( !aShape.IsNull() ) {
348       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
349       aLabel = STool->FindShape(aShape);
350     }
351   }
352   if ( !aLabel.IsNull() ) {
353     aPoint.SetX(Draw::Atof(argv[3]));
354     aPoint.SetY(Draw::Atof(argv[4]));
355     aPoint.SetZ(Draw::Atof(argv[5]));
356     Handle(XCAFDoc_Centroid) aCentroid = new XCAFDoc_Centroid;
357     if (!aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) aLabel.AddAttribute(aCentroid);
358     aCentroid->Set(aPoint);
359     di << Draw::Atof(argv[3])<<" "<<Draw::Atof(argv[4])<<" "<<Draw::Atof(argv[5]);
360   }
361   return 0;
362 }
363
364
365 //=======================================================================
366 //function : GetVolume
367 //purpose  : 
368 //=======================================================================
369
370 static Standard_Integer GetVolume (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
371 {
372   if (argc!=3) {
373     di<<"Use: "<<argv[0]<<" DocName {Shape|Label}\n";
374     return 1;
375   }
376   Handle(TDocStd_Document) Doc;
377   DDocStd::GetDocument(argv[1], Doc);
378   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
379   
380   TDF_Label aLabel;
381   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
382   if ( aLabel.IsNull() ) {
383     TopoDS_Shape aShape= DBRep::Get(argv[2]);
384     if ( !aShape.IsNull() ) {
385       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
386       aLabel = STool->FindShape(aShape);
387     }
388   }
389   if ( !aLabel.IsNull() ) {
390 //    Handle(XCAFDoc_Volume) aVolume = new (XCAFDoc_Volume);
391 //    if (aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume)) di << aVolume->Get();
392     // another case
393     Standard_Real aVol;
394     if(XCAFDoc_Volume::Get(aLabel, aVol))
395       di << aVol;
396   }
397   return 0;
398 }
399
400
401 //=======================================================================
402 //function : GetArea
403 //purpose  : 
404 //=======================================================================
405
406 static Standard_Integer GetArea (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
407 {
408   if (argc!=3) {
409     di<<"Use: "<<argv[0]<<" DocName {Shape|Label}\n";
410     return 1;
411   }
412   Handle(TDocStd_Document) Doc;
413   DDocStd::GetDocument(argv[1], Doc);
414   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
415   
416   TDF_Label aLabel;
417   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
418   if ( aLabel.IsNull() ) {
419     TopoDS_Shape aShape= DBRep::Get(argv[2]);
420     if ( !aShape.IsNull() ) {
421       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
422       aLabel = STool->FindShape(aShape);
423     }
424   }
425   if ( !aLabel.IsNull() ) {
426 //     Handle(XCAFDoc_Area) aArea = new (XCAFDoc_Area);
427 //     if (aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea)) di << aArea->Get();
428     // another case
429     Standard_Real anA;
430     if(XCAFDoc_Area::Get(aLabel, anA))
431       di << anA;
432   }
433   return 0;
434 }
435
436
437 //=======================================================================
438 //function : GetCentroid
439 //purpose  : 
440 //=======================================================================
441
442 static Standard_Integer GetCentroid (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
443 {
444   if (argc!=3) {
445     di<<"Use: "<<argv[0]<<" DocName {Shape|Label} \n";
446     return 1;
447   }
448   Handle(TDocStd_Document) Doc;
449   DDocStd::GetDocument(argv[1], Doc);
450   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
451   
452   gp_Pnt aPoint;
453   
454   TDF_Label aLabel;
455   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
456   if ( aLabel.IsNull() ) {
457     TopoDS_Shape aShape= DBRep::Get(argv[2]);
458     if ( !aShape.IsNull() ) {
459       Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
460       aLabel = STool->FindShape(aShape);
461     }
462   }
463   if ( !aLabel.IsNull() ) {
464     Handle(XCAFDoc_Centroid) aCentroid = new (XCAFDoc_Centroid);
465     if (aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) {
466 //       aPoint = aCentroid->Get();
467 //       di << aPoint.X()<<" "<<aPoint.Y()<<" "<<aPoint.Z();
468       // another case
469       if(XCAFDoc_Centroid::Get(aLabel, aPoint))
470         di << aPoint.X()<<" "<<aPoint.Y()<<" "<<aPoint.Z();
471     }
472   }
473   return 0;
474 }
475
476 //=======================================================================
477 //function : CheckProps
478 //purpose  : 
479 //=======================================================================
480
481 static Standard_Integer CheckProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
482 {
483   if (argc <2) {
484     di << "Use: "<<argv[0]<<" DocName [ 0|deflection [Shape|Label] ]\n";
485     di << "     If second argument is 0, standard CADCADE tool is used for\n";
486     di << "     computation of volume and CG.\n";
487     di << "     If second argument is not 0, it is treated as deflection\n";
488     di << "     and computation is done by triangulations\n";
489     di << "     If the second argument is negative, meshing is forced\n";
490     return 1;
491   }
492   Handle(TDocStd_Document) Doc;
493   DDocStd::GetDocument(argv[1], Doc);
494   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
495   Standard_Boolean withVolFix = Standard_False;
496   if ( argc >2 && Draw::Atof(argv[2]) != 0 ) withVolFix = Standard_True;
497   Standard_Boolean wholeDoc = ( argc <4 );
498   TDF_LabelSequence seq;
499   if ( ! wholeDoc ) {
500     TDF_Label aLabel;
501     TDF_Tool::Label(Doc->GetData(), argv[3], aLabel);
502     TopoDS_Shape aShape;
503     if ( aLabel.IsNull() ) {
504       aShape= DBRep::Get(argv[3]);
505       if ( !aShape.IsNull() ) {
506         Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
507         aLabel = STool->FindShape(aShape);
508       }
509     }
510     if ( aLabel.IsNull() ) return 1;
511     seq.Append ( aLabel );
512   }
513   else {
514     Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
515     STool->GetShapes(seq);
516   }
517   if ( wholeDoc ) {
518     di << "Label            Area defect   Volume defect    dX      dY      dZ    Name\n";
519   }
520   for ( Standard_Integer i=1; i <= seq.Length(); i++ ) {
521     TDF_Label aLabel = seq(i);
522     
523     // add instance labels to sequence to process them as well
524     if ( XCAFDoc_ShapeTool::IsAssembly ( aLabel ) ) {
525       TDF_LabelSequence comp;
526       XCAFDoc_ShapeTool::GetComponents ( aLabel, comp );
527       Standard_Integer m=i;
528       for ( Standard_Integer k=1; k <= comp.Length(); k++ ) {
529         TDF_Label lab = comp(k);
530         Handle(XCAFDoc_Volume) aVolume;
531         Handle(XCAFDoc_Area) aArea;
532         Handle(XCAFDoc_Centroid) aCentroid;
533         if ( ! lab.FindAttribute (XCAFDoc_Volume::GetID(), aVolume) &&
534              ! lab.FindAttribute (XCAFDoc_Area::GetID(), aArea) &&
535              ! lab.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid) ) continue;
536         seq.InsertAfter ( m++, lab );
537       }
538     }
539
540     TCollection_AsciiString str;
541     TDF_Tool::Entry ( aLabel, str );
542     //printf ( "%s%-12.12s", ( wholeDoc ? "" : "Label " ), str.ToCString() );
543     //fflush ( stdout );
544     char string1[260];
545     Sprintf (string1, "%s%-12.12s", ( wholeDoc ? "" : "Label " ), str.ToCString() );
546     di << string1;
547     Handle(TDataStd_Name) N;
548     if ( aLabel.FindAttribute ( TDataStd_Name::GetID(), N ) && ! wholeDoc ) {
549       TCollection_AsciiString name(N->Get(), '?');
550       di << " \"" << name.ToCString() << "\"";
551     }
552     if ( ! wholeDoc ) di << "\n";
553     
554     Handle(XCAFDoc_Volume) aVolume;
555     Handle(XCAFDoc_Area) aArea;
556     Handle(XCAFDoc_Centroid) aCentroid;
557     aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume);
558     aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea);
559     aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid);
560     GProp_GProps G;
561
562     TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape ( aLabel );
563     if ( ! aArea.IsNull() ) {
564       try { 
565         OCC_CATCH_SIGNALS
566         BRepGProp::SurfaceProperties(aShape,G,0.001);
567         //printf ("%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : "  Area defect:   " ),
568         //      aArea->Get() - G.Mass(), 
569         //      (Standard_Integer)( Abs ( G.Mass() ) > 1e-10 ? 100. * ( aArea->Get() - G.Mass() ) / G.Mass() : 999. ),
570         //      ( wholeDoc ? "" : "\n" ));
571         char string2[260];
572         Sprintf (string2, "%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : "  Area defect:   " ),
573                  aArea->Get() - G.Mass(), 
574                  (Standard_Integer)( Abs ( G.Mass() ) > 1e-10 ? 100. * ( aArea->Get() - G.Mass() ) / G.Mass() : 999. ),
575                  ( wholeDoc ? "" : "\n" ));
576         di << string2;
577       }
578       catch (Standard_Failure const&) {
579         //printf ( "%-16.16s", "exception" );
580         char string3[260];
581         Sprintf (string3, "%-16.16s", "exception" );
582         di << string3;
583       }
584     }
585     else if ( wholeDoc ) {
586       //printf ( "%16.16s", "" );
587       char string4[260];
588       Sprintf (string4, "%16.16s", "" );
589       di << string4;
590     }
591
592     if ( ! aVolume.IsNull() || ! aCentroid.IsNull() ) {
593       try {
594         OCC_CATCH_SIGNALS
595         // Added for check Volume. PTV 08 Nov 2000.     
596         Standard_Real localVolume;
597         gp_Pnt pcg(0,0,0);
598         if ( withVolFix ) {
599           Standard_Real tol = Draw::Atof(argv[2]);
600           Standard_Boolean withForce = Standard_False;
601           if ( tol < 0 ) {
602             withForce = Standard_True;
603             tol = -tol;
604           }
605           localVolume = CalculVolume(aShape, pcg, tol, withForce, di);
606         }
607         else {
608           BRepGProp::VolumeProperties(aShape,G,0.001,Standard_True);
609           localVolume = G.Mass();
610           pcg = G.CentreOfMass();
611         }
612         
613         if ( ! aVolume.IsNull() ) {
614           //printf ("%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : "  Volume defect: " ),
615                 //  aVolume->Get() - localVolume,
616                 //  (Standard_Integer)( Abs ( localVolume ) > 1e-10 ? 100. * ( aVolume->Get() - localVolume ) / localVolume : 999. ),
617                 //  ( wholeDoc ? "" : "\n" ));
618           char string5[260];
619           Sprintf (string5, "%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : "  Volume defect: " ),
620                    aVolume->Get() - localVolume,
621                    (Standard_Integer)( Abs ( localVolume ) > 1e-10 ? 100. * ( aVolume->Get() - localVolume ) / localVolume : 999. ),
622                    ( wholeDoc ? "" : "\n" ));
623           di << string5;
624         }
625         else if ( wholeDoc ) {
626           //printf ( "%16.16s", "" );
627           char string6[260];
628           Sprintf (string6, "%16.16s", "" );
629           di << string6;
630         }
631
632         if ( ! aCentroid.IsNull() ) {
633           gp_Pnt p = aCentroid->Get();
634           char string7[260];
635           if ( wholeDoc ) {
636             //printf ( " %7.2f %7.2f %7.2f", 
637                 //    p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() );
638             Sprintf (string7, " %7.2f %7.2f %7.2f", 
639                     p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() );
640           } else {
641             //printf ( "  CG defect: dX=%.3f, dY=%.3f, dZ=%.3f\n", 
642                 //    p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() );
643             Sprintf (string7, "  CG defect: dX=%.3f, dY=%.3f, dZ=%.3f\n", 
644                     p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() );
645           }
646           di << string7;
647         }
648         else if ( wholeDoc ) {
649           //printf ( "%24.24s", "" );
650           char string8[260];
651           Sprintf (string8, "%24.24s", "" );
652           di << string8;
653         }
654       }
655       catch (Standard_Failure const& anException) {
656         //printf ( "%40.40s", "exception" );
657         char string9[260];
658         Sprintf (string9, "%40.40s", "exception" );
659         di << string9;
660 #ifdef OCCT_DEBUG
661         //fflush ( stdout );
662         di << ": ";
663         di << anException.GetMessageString();
664         di<<" ** Skip\n";
665 #endif
666         (void)anException;
667       }
668     }
669     else if ( wholeDoc ) {
670       //printf ( "%40.40s", "" );
671       char string10[260];
672       Sprintf (string10, "%40.40s", "" );
673       di << string10;
674     }
675     //fflush ( stdout );
676
677     if ( wholeDoc ) {
678       if ( ! N.IsNull() ) {
679         TCollection_AsciiString name(N->Get(),'?');
680         di << "  \"" << name.ToCString() << "\"";
681       }
682       di << "\n";
683     }
684   }
685   return 0;
686 }
687
688
689 //=======================================================================
690 //function : ShapeVolume
691 //purpose  : 
692 //=======================================================================
693
694 static Standard_Integer ShapeVolume (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
695 {
696   if (argc!=3) {
697     di<<"Use: "<<argv[0]<<" Shape deflection \n";
698     return 1;
699   }
700   TopoDS_Shape aShape = DBRep::Get(argv[1]);
701   if (aShape.IsNull()) return 1;
702   gp_Pnt aPoint(0,0,0);
703   Standard_Real localVolume;
704   Standard_Real tol = Draw::Atof(argv[2]);
705   Standard_Boolean withForce = Standard_False;
706   if ( tol < 0 ) {
707     withForce = Standard_True;
708     tol = -tol;
709   }
710   localVolume = CalculVolume(aShape, aPoint, tol, withForce, di);
711   //std::cout << "Volume : " << std::setw(15) << localVolume << "\n" << std::endl;
712   Standard_SStream aSStream;
713   aSStream << "Volume : " << std::setw(15) << localVolume << "\n";
714   di << aSStream;
715   return 0;
716 }
717
718
719 //=======================================================================
720 //function : GetMassProps
721 //purpose  : auxilary for ShapeMassProps
722 //=======================================================================
723
724 static Standard_Boolean GetMassProps(const TDF_Label& aLabel, gp_XYZ& theCenterGravity,
725                                      Standard_Real& theMassVal, const Standard_Real thetol)
726 {
727   Standard_Real aDensity = XCAFDoc_MaterialTool::GetDensityForShape(aLabel);
728
729   if(aDensity >0) {
730     TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape(aLabel);
731     GProp_GProps G;
732     BRepGProp::VolumeProperties(aShape,G,0.001,Standard_True);
733     Standard_Real localVolume = G.Mass();
734     theMassVal = aDensity*localVolume;
735     theCenterGravity = G.CentreOfMass().XYZ();
736     return Standard_True;
737   }
738
739   if(aDensity==0) {
740     Handle(TNaming_NamedShape) NS;
741     if(aLabel.FindAttribute(TNaming_NamedShape::GetID(),NS)) {
742       //S = TNaming_Tool::GetShape(NS);
743       TopoDS_Shape aSh = NS->Get();
744       if(aSh.ShapeType()==TopAbs_SOLID) return Standard_False;
745     }
746
747     //TopoDS_Shape aSh = XCAFDoc_ShapeTool::GetShape(aLabel);
748     //if(aSh.ShapeType()==TopAbs_SOLID) return Standard_False;
749
750     Handle(TDataStd_TreeNode) Node;
751     if( aLabel.FindAttribute(XCAFDoc::ShapeRefGUID(),Node) && Node->HasFather() ) {
752       TDF_Label SubL = Node->Father()->Label();
753       if(GetMassProps(SubL,theCenterGravity,theMassVal,thetol)) {
754         Handle(XCAFDoc_Location) LocationAttribute;
755         if(aLabel.FindAttribute(XCAFDoc_Location::GetID(),LocationAttribute)) {
756           gp_XYZ tmp = LocationAttribute->Get().Transformation().TranslationPart();
757           theCenterGravity += tmp;
758         }
759         return Standard_True;
760       }
761       else
762         return Standard_False;
763     }
764     else {
765       // calculate for components
766       TDF_LabelSequence comp;
767       XCAFDoc_ShapeTool::GetComponents ( aLabel, comp );
768       if(!comp.Length())
769         return Standard_False;
770   
771       TColgp_Array1OfXYZ anArrCentres(1,comp.Length());
772       TColStd_Array1OfReal anArrMass(1,comp.Length());
773       anArrMass.Init(0.0);
774       Standard_Real aTotalMass =0.0;
775       Standard_Integer k=1;
776       for ( ; k <= comp.Length(); k++ ) {
777         TDF_Label lab = comp(k);
778         gp_XYZ aCenterGravity(0.0,0.0,0.0);
779         Standard_Real aMassVal =0.0;
780         if(GetMassProps(lab,aCenterGravity,aMassVal,thetol)) {
781           anArrCentres.SetValue(k,aCenterGravity);
782           anArrMass.SetValue(k,aMassVal);
783           aTotalMass += aMassVal;
784         }
785       }
786       if(aTotalMass>0) {
787         Standard_Real x= 0.0, y =0.0, z= 0.0;
788         for( k=1; k <= anArrMass.Length(); k++) {
789           Standard_Real koef = anArrMass.Value(k)/aTotalMass;
790           x+= (anArrCentres.Value(k).X()*koef);
791           y+= (anArrCentres.Value(k).Y()*koef);
792           z+= (anArrCentres.Value(k).Z()*koef);
793         }
794         theMassVal = aTotalMass;
795         theCenterGravity.SetCoord(x,y,z);
796       }
797     }
798   }
799   return Standard_True;
800 }
801
802
803 //=======================================================================
804 //function : ShapeMassProps
805 //purpose  : 
806 //=======================================================================
807
808 static Standard_Integer ShapeMassProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
809 {
810   
811   if (argc <2) {
812     di << "Use: "<<argv[0]<<" DocName [deflection [Shape|Label] ]\n";
813     di << "     If second argument is 0, standard CADCADE tool is used for\n";
814     di << "     computation of volume and CG.\n";
815     di << "     If second argument is not 0, it is treated as deflection\n";
816     di << "     and computation is done by triangulations\n";
817     di << "     If the second argument is negative, meshing is forced\n";
818     return 1;
819   }
820   Handle(TDocStd_Document) Doc;
821   DDocStd::GetDocument(argv[1], Doc);
822   Standard_Real atol = Precision::Confusion();
823   if(argc >2)
824     atol  = Draw::Atof(argv[2]);
825   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
826   Standard_Boolean wholeDoc = ( argc <4 );
827   TDF_LabelSequence seq;
828   if ( ! wholeDoc ) {
829     TDF_Label aLabel;
830     TDF_Tool::Label(Doc->GetData(), argv[3], aLabel);
831     TopoDS_Shape aShape;
832     if ( aLabel.IsNull() ) {
833       aShape= DBRep::Get(argv[3]);
834       if ( !aShape.IsNull() ) {
835         Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
836         aLabel = STool->FindShape(aShape);
837       }
838     }
839     if ( aLabel.IsNull() ) return 1;
840     seq.Append ( aLabel );
841   }
842   else {
843     Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
844     STool->GetShapes(seq);
845   }
846   //if ( wholeDoc ) {
847   //  di << "Label            Area defect   Volume defect    dX      dY      dZ    Name\n";
848  // }
849   gp_XYZ aCenterGravity(0.0,0.0,0.0);
850   Standard_Real aMassVal =0.0;
851   for ( Standard_Integer i=1; i <= seq.Length(); i++ ) {
852     TDF_Label aLabel = seq(i);
853     GetMassProps(aLabel,aCenterGravity,aMassVal,atol);
854 //    if(GetMassProps(aLabel,aCenterGravity,aMassVal,atol))
855 //    {
856       TCollection_AsciiString str;
857       TDF_Tool::Entry ( aLabel, str );
858     if(aMassVal>0) {
859       di<<"Shape from label : "<<str.ToCString()<<"\n";
860       di<<"Mass = "<<aMassVal<<"\n";
861       di<<"CenterOfGravity X = "<<aCenterGravity.X()<<",Y = "<<aCenterGravity.Y()<<",Z = "<<aCenterGravity.Z()<<"\n";
862       di<<"\n";
863     }
864     else {
865 //      di<<"For one component density is absent\n";
866       di<<"Shape from label : "<<str.ToCString()<<" not have a mass\n";
867     }
868   }
869   return 0;
870 }
871
872
873 //=======================================================================
874 //function : SetMaterial
875 //purpose  : 
876 //=======================================================================
877
878 static Standard_Integer SetMaterial (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
879 {
880   if (argc<5) {
881     di<<"Use: "<<argv[0]<<" Doc {Label|Shape} name density(g/cu sm) \n";
882     return 1;
883   }
884   Handle(TDocStd_Document) Doc;   
885   DDocStd::GetDocument(argv[1], Doc);
886   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
887   
888   TDF_Label aLabel;
889   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
890
891   Handle(XCAFDoc_MaterialTool) MatTool = XCAFDoc_DocumentTool::MaterialTool(Doc->Main());
892
893   MatTool->SetMaterial(aLabel, new TCollection_HAsciiString(argv[3]),
894                        new TCollection_HAsciiString(""), Draw::Atof(argv[4]),
895                        new TCollection_HAsciiString("density measure"),
896                        new TCollection_HAsciiString("POSITIVE_RATIO_MEASURE"));
897
898   return 0;
899 }
900
901 static Standard_Integer GetValidationProps(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
902 {
903   if (argc< 2) {
904     di<<"Use: "<<argv[0]<<" Doc {Label|Shape}\n";
905     return 1;
906   }
907   Handle(TDocStd_Document) Doc;   
908   DDocStd::GetDocument(argv[1], Doc);
909   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
910   Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
911   TDF_LabelSequence aLabels;
912   if( argc == 2)
913     STool->GetShapes (aLabels);
914   else
915   {
916     TDF_Label aLabel;
917     TopoDS_Shape aShape = DBRep::Get(argv[2]);
918     if( aShape.IsNull())
919     {
920       TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
921     }
922     else
923     {
924       aLabel = STool->FindShape(aShape);
925     }
926     if( !aLabel.IsNull())
927       aLabels.Append(aLabel);
928   }
929    
930   
931   enum
932   {
933     Vol =0,
934     Area = 1,
935     Centroid = 2
936   };
937   Standard_Integer nbProps[3];
938   Standard_Integer j =0;
939   for( ; j <= Centroid; j++)
940     nbProps[j] = 0;
941   Standard_Integer i = 1;
942   for( ; i <= aLabels.Length() ; i++)
943   {
944     TDF_Label aLabel = aLabels(i);
945     
946     Standard_Real aProp[2];
947     
948     aProp[0] = 0.;
949     aProp[1] = 0.;
950     
951
952     gp_Pnt aP(Precision::Infinite(), Precision::Infinite(), Precision::Infinite());
953     XCAFDoc_Volume::Get(aLabel, aProp[Vol]);
954     XCAFDoc_Area::Get(aLabel, aProp[Area]);
955
956     Handle(XCAFDoc_Centroid) aCentroid = new (XCAFDoc_Centroid);
957     if (aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) 
958       XCAFDoc_Centroid::Get(aLabel, aP);
959         
960     if(aProp[Vol] > 0 || aProp[Area] > 0 || !Precision::IsInfinite(aP.X()) )
961     {
962       TCollection_AsciiString str;
963       TDF_Tool::Entry ( aLabel, str );
964       di<<"Label : "<<str;
965       
966       for(j = 0 ; j <= Area; j++)
967       {
968         if( aProp[j] > 0)
969         {
970           di<<(j == Vol ? "; Volume - " : "; Area - ")<<aProp[j];
971           nbProps[j]++;
972         }
973       }
974
975       if( !Precision::IsInfinite(aP.X()) )
976       {      
977         di<< "; Centroid -  "<< aP.X()<<" "<<aP.Y()<<" "<<aP.Z();
978         nbProps[Centroid]++;
979       }
980        di<<"\n";
981     }
982   }
983   di<<"========================================================="<<"\n";
984   di<< "Number of the validation properties : ";
985   for( i = Vol; i <= Centroid; i++)
986     di<< ( i == Vol ? "Volume" : (i == Area ? "Area" : "Centroid"))<<" : "<<nbProps[i]<<" ; "; 
987     
988   di<<"\n";
989   return 0;
990 }
991
992 //=======================================================================
993 //function : InitCommands
994 //purpose  : 
995 //=======================================================================
996
997 void XDEDRAW_Props::InitCommands(Draw_Interpretor& di) 
998 {
999   static Standard_Boolean initactor = Standard_False;
1000   if (initactor)
1001   {
1002     return;
1003   }
1004   initactor = Standard_True;
1005
1006   Standard_CString g = "XDE property's commands";
1007   
1008   di.Add ("XSetVolume","DocName {Label|Shape} volume \t: Seting volume to shape",
1009                    __FILE__, SetVolume, g);
1010
1011   di.Add ("XGetVolume","DocName {Shape|Label} \t: Getting volume of shape",
1012                    __FILE__, GetVolume, g);
1013
1014   di.Add ("XSetArea","DocName {Label|Shape} area \t: Seting area to shape",
1015                    __FILE__, SetArea, g);
1016
1017   di.Add ("XGetArea","DocName {Shape|Label} \t: Getting area of shape",
1018                    __FILE__, GetArea, g);
1019
1020   di.Add ("XSetCentroid","DocName  {Label|Shape} x y z \t: Seting centroid to shape",
1021                    __FILE__, SetCentroid, g);
1022
1023   di.Add ("XGetCentroid","DocName {Shape|Label} \t: Getting centroid of shape ",
1024                    __FILE__, GetCentroid, g);
1025
1026   di.Add ("XSetProps","DocName {Shape|Label} [epsilon = 0.001] \t: Compute properties for shape ",
1027                    __FILE__, SetProps, g);
1028
1029   di.Add ("XCheckProps","DocName [ 0|deflection [Shape|Label] ]\t: Check properties recorded for shape ",
1030                    __FILE__, CheckProps, g);
1031   di.Add ("XShapeVolume","Shape \t: Calculating volume of shape",
1032                    __FILE__, ShapeVolume, g);
1033   di.Add ("XShapeMassProps","XShapeMassProps DocName [deflection [Shape|Label] ]\t: Get mass value and center of gravity for shape ",
1034                    __FILE__,ShapeMassProps , g);
1035   di.Add ("XSetMaterial","Doc {Label|Shape} name density(g/cu sm) \t: Set material to shape given by Label",
1036                    __FILE__, SetMaterial, g);
1037   di.Add ("XGetValProps","Doc {Label|Shape}",__FILE__, GetValidationProps, g);
1038  
1039 }