5a217c61a5efce85264b3fefaf8d16d61d26a589
[occt.git] / src / XCAFDoc / XCAFDoc_ColorTool.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #include <XCAFDoc_ColorTool.ixx>
19 #include <XCAFDoc.hxx>
20 #include <XCAFDoc_Color.hxx>
21
22 #include <TDF_ChildIDIterator.hxx>
23 #include <TDataStd_TreeNode.hxx>
24 #include <TDataStd_Name.hxx>
25 #include <TNaming_NamedShape.hxx>
26 #include <XCAFDoc_DocumentTool.hxx>
27 #include <XCAFDoc_Color.hxx>
28 #include <TDataStd_UAttribute.hxx>
29 #include <XCAFDoc_GraphNode.hxx>
30
31 #define AUTONAMING // automatically set names for labels
32
33 //=======================================================================
34 //function : BaseLabel
35 //purpose  : 
36 //=======================================================================
37
38 TDF_Label XCAFDoc_ColorTool::BaseLabel() const
39 {
40   return Label();
41 }
42 //=======================================================================
43 //function : ShapeTool
44 //purpose  : 
45 //=======================================================================
46
47 const Handle(XCAFDoc_ShapeTool)& XCAFDoc_ColorTool::ShapeTool() 
48 {
49   if (myShapeTool.IsNull())
50     myShapeTool = XCAFDoc_DocumentTool::ShapeTool(Label());
51   return myShapeTool;
52 }
53
54
55 //=======================================================================
56 //function : IsColor
57 //purpose  : 
58 //=======================================================================
59
60 Standard_Boolean XCAFDoc_ColorTool::IsColor (const TDF_Label& lab) const
61 {
62   Quantity_Color C;
63   return GetColor ( lab, C );
64 }
65
66 //=======================================================================
67 //function : GetColor
68 //purpose  : 
69 //=======================================================================
70
71 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& lab,
72                                                Quantity_Color& col) const
73 {
74   if ( lab.Father() != Label() ) return Standard_False;
75   
76   Handle(XCAFDoc_Color) ColorAttribute;
77   if ( ! lab.FindAttribute ( XCAFDoc_Color::GetID(), ColorAttribute ))
78     return Standard_False;
79   
80   col = ColorAttribute->GetColor();
81   
82   return Standard_True;
83 }
84
85 //=======================================================================
86 //function : FindColor
87 //purpose  : 
88 //=======================================================================
89
90 Standard_Boolean XCAFDoc_ColorTool::FindColor (const Quantity_Color& col, TDF_Label& lab) const
91 {
92   TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
93   for (; it.More(); it.Next()) {
94     TDF_Label aLabel = it.Value()->Label();
95     Quantity_Color C;
96     if ( ! GetColor ( aLabel, C ) ) continue;
97     if ( C.IsEqual ( col ) ) {
98       lab = aLabel;
99       return Standard_True;
100     }
101   }
102   return Standard_False;
103 }
104
105 //=======================================================================
106 //function : FindColor
107 //purpose  : 
108 //=======================================================================
109
110 TDF_Label XCAFDoc_ColorTool::FindColor (const Quantity_Color& col) const
111 {
112   TDF_Label L;
113   FindColor ( col, L );
114   return L;
115 }
116
117 //=======================================================================
118 //function : AddColor
119 //purpose  : 
120 //=======================================================================
121
122 TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_Color& col) const
123 {
124   TDF_Label L;
125   if ( FindColor ( col, L ) ) return L;
126
127   // create a new color entry
128   
129   TDF_TagSource aTag;
130   L = aTag.NewChild ( Label() );
131
132   XCAFDoc_Color::Set(L, col);
133   
134 #ifdef AUTONAMING
135   // set name according to color value
136   TCollection_AsciiString str;
137   str += col.StringName ( col.Name() );
138   str += " (";
139   str += TCollection_AsciiString ( col.Red() );
140   str += ",";
141   str += TCollection_AsciiString ( col.Green() );
142   str += ",";
143   str += TCollection_AsciiString ( col.Blue() );
144   str += ")";
145   TDataStd_Name::Set ( L, str );
146 #endif
147   
148   return L;
149 }
150
151 //=======================================================================
152 //function : RemoveColor
153 //purpose  : 
154 //=======================================================================
155
156 void XCAFDoc_ColorTool::RemoveColor (const TDF_Label& lab) const
157 {
158   lab.ForgetAllAttributes (Standard_True);
159 }
160
161 //=======================================================================
162 //function : GetColors
163 //purpose  : 
164 //=======================================================================
165
166 void XCAFDoc_ColorTool::GetColors (TDF_LabelSequence& Labels) const
167 {
168   Labels.Clear();
169
170   TDF_ChildIDIterator ChildIDIterator(Label(),XCAFDoc_Color::GetID()); 
171   for (; ChildIDIterator.More(); ChildIDIterator.Next()) {
172     TDF_Label L = ChildIDIterator.Value()->Label();
173     if ( IsColor ( L ) ) Labels.Append ( L );
174   }
175 }
176
177 //=======================================================================
178 //function : SetColor
179 //purpose  : 
180 //=======================================================================
181
182 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
183                                const TDF_Label& colorL,
184                                const XCAFDoc_ColorType type) const
185 {
186   // set reference
187   Handle(TDataStd_TreeNode) refNode, mainNode;
188   mainNode = TDataStd_TreeNode::Set ( colorL, XCAFDoc::ColorRefGUID(type) );
189   refNode  = TDataStd_TreeNode::Set ( L,      XCAFDoc::ColorRefGUID(type) );
190   refNode->Remove(); // abv: fix against bug in TreeNode::Append()
191   mainNode->Prepend(refNode);
192 }
193
194 //=======================================================================
195 //function : SetColor
196 //purpose  : 
197 //=======================================================================
198
199 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
200                                const Quantity_Color& Color,
201                                const XCAFDoc_ColorType type) const
202 {
203   TDF_Label colorL = AddColor ( Color );
204   SetColor ( L, colorL, type );
205 }
206
207 //=======================================================================
208 //function : UnSetColor
209 //purpose  : 
210 //=======================================================================
211
212 void XCAFDoc_ColorTool::UnSetColor (const TDF_Label& L, const XCAFDoc_ColorType type) const
213 {
214   L.ForgetAttribute ( XCAFDoc::ColorRefGUID(type) );
215 }
216
217 //=======================================================================
218 //function : IsSet
219 //purpose  : 
220 //=======================================================================
221
222 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TDF_Label& L, const XCAFDoc_ColorType type) const
223 {
224   Handle(TDataStd_TreeNode) Node;
225   return L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) && Node->HasFather();
226 }
227
228 //=======================================================================
229 //function : GetColor
230 //purpose  : 
231 //=======================================================================
232
233 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
234                                            const XCAFDoc_ColorType type,
235                                            TDF_Label& colorL) 
236 {
237   Handle(TDataStd_TreeNode) Node;
238   if ( ! L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) ||
239        ! Node->HasFather() ) return Standard_False;
240   colorL = Node->Father()->Label();
241   return Standard_True;
242 }
243
244 //=======================================================================
245 //function : GetColor
246 //purpose  : 
247 //=======================================================================
248
249 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
250                                            const XCAFDoc_ColorType type,
251                                            Quantity_Color& color) 
252 {
253   TDF_Label colorL;
254   if ( ! GetColor ( L, type, colorL ) ) return Standard_False;
255   return GetColor ( colorL, color );
256 }
257
258 //=======================================================================
259 //function : SetColor
260 //purpose  : 
261 //=======================================================================
262
263 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
264                                            const TDF_Label& colorL,
265                                            const XCAFDoc_ColorType type) 
266 {
267   TDF_Label L;
268   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
269   SetColor ( L, colorL, type );
270   return Standard_True;
271 }
272
273 //=======================================================================
274 //function : SetColor
275 //purpose  : 
276 //=======================================================================
277
278 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
279                                            const Quantity_Color& Color,
280                                            const XCAFDoc_ColorType type) 
281 {
282   TDF_Label colorL = AddColor ( Color );
283   return SetColor ( S, colorL, type );
284 }
285
286 //=======================================================================
287 //function : UnSetColor
288 //purpose  : 
289 //=======================================================================
290
291 Standard_Boolean XCAFDoc_ColorTool::UnSetColor (const TopoDS_Shape& S,
292                                              const XCAFDoc_ColorType type) 
293 {
294   TDF_Label L;
295   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
296   UnSetColor ( L, type );
297   return Standard_True;
298 }
299
300 //=======================================================================
301 //function : IsSet
302 //purpose  : 
303 //=======================================================================
304
305 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TopoDS_Shape& S,
306                                         const XCAFDoc_ColorType type) 
307 {
308   TDF_Label L;
309   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
310   return IsSet ( L, type );
311 }
312
313 //=======================================================================
314 //function : GetColor
315 //purpose  : 
316 //=======================================================================
317
318 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S, 
319                                            const XCAFDoc_ColorType type,
320                                            TDF_Label& colorL) 
321 {
322   TDF_Label L;
323   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
324   return GetColor ( L, type, colorL );
325 }
326
327 //=======================================================================
328 //function : GetColor
329 //purpose  : 
330 //=======================================================================
331
332 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S,
333                                            const XCAFDoc_ColorType type,
334                                            Quantity_Color& color) 
335 {
336   TDF_Label colorL;
337   if ( ! GetColor ( S, type, colorL ) ) return Standard_False;
338   return GetColor ( colorL, color );
339 }
340
341 //=======================================================================
342 //function : GetID
343 //purpose  : 
344 //=======================================================================
345
346 const Standard_GUID& XCAFDoc_ColorTool::GetID() 
347 {
348   static Standard_GUID ColorTblID ("efd212ed-6dfd-11d4-b9c8-0060b0ee281b");
349   return ColorTblID; 
350 }
351
352 //=======================================================================
353 //function : Set
354 //purpose  : 
355 //=======================================================================
356
357 Handle(XCAFDoc_ColorTool) XCAFDoc_ColorTool::Set(const TDF_Label& L) 
358 {
359   Handle(XCAFDoc_ColorTool) A;
360   if (!L.FindAttribute (XCAFDoc_ColorTool::GetID(), A)) {
361     A = new XCAFDoc_ColorTool ();
362     L.AddAttribute(A);
363     A->myShapeTool = XCAFDoc_DocumentTool::ShapeTool(L);
364   }
365   return A;
366 }
367
368 //=======================================================================
369 //function : ID
370 //purpose  : 
371 //=======================================================================
372
373 const Standard_GUID& XCAFDoc_ColorTool::ID() const
374 {
375   return GetID();
376 }
377
378 //=======================================================================
379 //function : Restore
380 //purpose  : 
381 //=======================================================================
382
383 void XCAFDoc_ColorTool::Restore(const Handle(TDF_Attribute)& /*with*/) 
384 {
385 }
386
387 //=======================================================================
388 //function : NewEmpty
389 //purpose  : 
390 //=======================================================================
391
392 Handle(TDF_Attribute) XCAFDoc_ColorTool::NewEmpty() const
393 {
394   return new XCAFDoc_ColorTool;
395 }
396
397 //=======================================================================
398 //function : Paste
399 //purpose  : 
400 //=======================================================================
401
402 void XCAFDoc_ColorTool::Paste (const Handle(TDF_Attribute)& /*into*/,
403                                const Handle(TDF_RelocationTable)& /*RT*/) const
404 {
405 }
406
407 /**/
408
409 //=======================================================================
410 //function : XCAFDoc_ColorTool
411 //purpose  : 
412 //=======================================================================
413
414 XCAFDoc_ColorTool::XCAFDoc_ColorTool()
415 {
416 }
417
418 // PTV 23.01.2003 add visibility flag for objects (CAX-IF TRJ11)
419 //=======================================================================
420 //function : IsVisible
421 //purpose  : 
422 //=======================================================================
423
424 Standard_Boolean XCAFDoc_ColorTool::IsVisible (const TDF_Label& L) const
425 {
426   Handle(TDataStd_UAttribute) aUAttr;
427   return (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr));
428 }
429
430 //=======================================================================
431 //function : SetVisibility
432 //purpose  : 
433 //=======================================================================
434
435 void XCAFDoc_ColorTool::SetVisibility (const TDF_Label& L,
436                                        const Standard_Boolean isvisible)
437 {
438   Handle(TDataStd_UAttribute) aUAttr;
439   if (! isvisible ) {
440     Handle(XCAFDoc_GraphNode) aSHUO;
441     if (ShapeTool()->IsShape(L) || ShapeTool()->GetSHUO( L, aSHUO ) )
442       if (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr))
443         aUAttr->Set( L, XCAFDoc::InvisibleGUID() );
444   }
445   else L.ForgetAttribute( XCAFDoc::InvisibleGUID() );
446 }
447
448 //=======================================================================
449 //function : SetInstanceColor
450 //purpose  : 
451 //=======================================================================
452
453 Standard_Boolean XCAFDoc_ColorTool::SetInstanceColor (const TopoDS_Shape& theShape,
454                                                       const XCAFDoc_ColorType type,
455                                                       const Quantity_Color& color,
456                                                       const Standard_Boolean IsCreateSHUO)
457 {
458   // find shuo label structure 
459   TDF_LabelSequence aLabels;
460   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
461     return Standard_False;
462   Handle(XCAFDoc_GraphNode) aSHUO;
463   // set the SHUO structure for this component if it is not exist
464   if ( !ShapeTool()->FindSHUO( aLabels, aSHUO ) ) {
465     if (aLabels.Length() == 1) {
466       // set color directly for component as NAUO
467       SetColor(aLabels.Value(1), color, type);
468       return Standard_True;
469     }
470     else if ( !IsCreateSHUO ||  !ShapeTool()->SetSHUO( aLabels, aSHUO ) ) {
471       return Standard_False;
472     }
473   }
474   TDF_Label aSHUOLabel = aSHUO->Label();
475   SetColor( aSHUOLabel, color, type );
476   return Standard_True;
477 }
478
479 //=======================================================================
480 //function : GetInstanceColor
481 //purpose  : 
482 //=======================================================================
483
484 Standard_Boolean XCAFDoc_ColorTool::GetInstanceColor (const TopoDS_Shape& theShape,
485                                                       const XCAFDoc_ColorType type,
486                                                       Quantity_Color& color)
487 {
488   // find shuo label structure 
489   TDF_LabelSequence aLabels;
490   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
491     return Standard_False;
492   Handle(XCAFDoc_GraphNode) aSHUO;
493   // get shuo from document by label structure
494   TDF_Label aCompLab = aLabels.Value(aLabels.Length());
495   while (aLabels.Length() > 1) {
496     if ( !ShapeTool()->FindSHUO( aLabels, aSHUO ) ) {
497       // try to find other shuo 
498       aLabels.Remove(aLabels.Length());
499       continue;
500     } else {
501       TDF_Label aSHUOLabel = aSHUO->Label();
502       if (GetColor ( aSHUOLabel, type, color ) )
503         return Standard_True;
504       else 
505         // try to find other shuo 
506         aLabels.Remove(aLabels.Length());
507     }
508   }
509   // attempt to get color exactly of component
510   if (GetColor( aCompLab, type, color ))
511     return Standard_True;
512   
513   // attempt to get color of solid
514   TopLoc_Location aLoc;
515   TopoDS_Shape S0 = theShape;
516   S0.Location( aLoc );
517   TDF_Label aRefLab = ShapeTool()->FindShape( S0 );
518   if (!aRefLab.IsNull())
519     return GetColor( aRefLab, type, color );
520   // no color assigned
521   return Standard_False;
522 }
523
524 //=======================================================================
525 //function : IsInstanceVisible
526 //purpose  : 
527 //=======================================================================
528
529 Standard_Boolean XCAFDoc_ColorTool::IsInstanceVisible (const TopoDS_Shape& theShape)
530 {
531   // check visibility status of top-level solid, cause it is have highest priority
532   TopLoc_Location NullLoc;
533   TopoDS_Shape S0 = theShape;
534   S0.Location( NullLoc );
535   TDF_Label aRefL = ShapeTool()->FindShape( S0 );
536   if (!aRefL.IsNull() && !IsVisible(aRefL))
537     return Standard_False;
538   // find shuo label structure 
539   TDF_LabelSequence aLabels;
540   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
541     return Standard_True;
542   TDF_Label aCompLab = aLabels.Value(aLabels.Length());
543   // visibility status of component withouts SHUO.
544   if (!IsVisible( aCompLab ))
545     return Standard_False;
546   // check by SHUO structure
547   TDF_LabelSequence aCurLabels;
548   aCurLabels.Append(aCompLab);
549   Standard_Integer i = aLabels.Length() - 1;
550   //   while (aCurLabels.Length() < aLabels.Length()) {
551   while (i >= 1) {
552     aCurLabels.Prepend( aLabels.Value(i--) );
553     // get shuo from document by label structure
554     Handle(XCAFDoc_GraphNode) aSHUO;
555     if ( !ShapeTool()->FindSHUO( aCurLabels, aSHUO ) )
556       continue;
557     if ( !IsVisible(aSHUO->Label()) )
558       return Standard_False;
559   }
560   return Standard_True; //visible, cause cannot find invisibility status
561 }
562
563
564 //=======================================================================
565 //function : ReverseTreeNodes
566 //purpose  : auxilary
567 //=======================================================================
568 static void ReverseTreeNodes(Handle(TDataStd_TreeNode)& mainNode)
569 {
570   if(mainNode->HasFirst()) {
571     Handle(TDataStd_TreeNode) tmpNode;
572     Handle(TDataStd_TreeNode) pNode = mainNode->First();
573     Handle(TDataStd_TreeNode) nNode = pNode->Next();
574     while(!nNode.IsNull()) {
575       tmpNode = pNode->Previous();
576       pNode->SetPrevious(nNode);
577       pNode->SetNext(tmpNode);
578       pNode = nNode;
579       nNode = pNode->Next();
580     }
581     tmpNode = pNode->Previous();
582     pNode->SetPrevious(nNode);
583     pNode->SetNext(tmpNode);
584     mainNode->SetFirst(pNode);
585   }
586 }
587
588
589 //=======================================================================
590 //function : ReverseChainsOfTreeNodes
591 //purpose  : 
592 //=======================================================================
593
594 Standard_Boolean XCAFDoc_ColorTool::ReverseChainsOfTreeNodes()
595 {
596   TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
597   for (; it.More(); it.Next()) {
598     TDF_Label aLabel = it.Value()->Label();
599     Handle(TDataStd_TreeNode) mainNode;
600     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorSurf),mainNode)) {
601       ReverseTreeNodes(mainNode);
602     }
603     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorCurv),mainNode)) {
604       ReverseTreeNodes(mainNode);
605     }
606     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorGen),mainNode)) {
607       ReverseTreeNodes(mainNode);
608     }
609   }
610   return Standard_True;
611 }