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