1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13 
14 
15 #include <IFSelect_PacketList.hxx>
16 #include <IGESData_IGESEntity.hxx>
17 #include <IGESData_IGESModel.hxx>
18 #include <IGESData_ViewKindEntity.hxx>
19 #include <IGESSelect_ViewSorter.hxx>
20 #include <Interface_EntityIterator.hxx>
21 #include <Interface_Graph.hxx>
22 #include <Interface_InterfaceModel.hxx>
23 #include <Interface_Macros.hxx>
24 #include <Standard_Transient.hxx>
25 #include <Standard_Type.hxx>
26 
IMPLEMENT_STANDARD_RTTIEXT(IGESSelect_ViewSorter,Standard_Transient)27 IMPLEMENT_STANDARD_RTTIEXT(IGESSelect_ViewSorter,Standard_Transient)
28 
29 #define PourDrawing 404
30 
31 
32 IGESSelect_ViewSorter::IGESSelect_ViewSorter  ()    {  }
33 
SetModel(const Handle (IGESData_IGESModel)& model)34     void  IGESSelect_ViewSorter::SetModel
35   (const Handle(IGESData_IGESModel)& model)    {  themodel = model;  }
36 
37 
Clear()38     void  IGESSelect_ViewSorter::Clear ()
39 {
40   Standard_Integer nb = themodel->NbEntities();
41   if (nb < 100) nb = 100;
42   themap.Clear();      themap.ReSize (nb);
43   theitems.Clear();    theitems.ReSize (nb);
44   thefinals.Clear();   thefinals.ReSize (nb);
45   theinditem.Clear();  theindfin.Clear();  // seq//
46 }
47 
48 
Add(const Handle (Standard_Transient)& ent)49     Standard_Boolean  IGESSelect_ViewSorter::Add
50   (const Handle(Standard_Transient)& ent)
51 {
52   DeclareAndCast(IGESData_IGESEntity,igesent,ent);
53   if (!igesent.IsNull()) return AddEntity (igesent);
54   DeclareAndCast(TColStd_HSequenceOfTransient,list,ent);
55   if (!list.IsNull())  {  AddList  (list);   return Standard_True;  }
56   DeclareAndCast(Interface_InterfaceModel,model,ent);
57   if (!model.IsNull()) {  AddModel (model);  return Standard_True;  }
58   return Standard_False;
59 }
60 
AddEntity(const Handle (IGESData_IGESEntity)& igesent)61     Standard_Boolean  IGESSelect_ViewSorter::AddEntity
62   (const Handle(IGESData_IGESEntity)& igesent)
63 {
64 //  Reception, controle de type et de map
65   if (igesent.IsNull()) return Standard_False;
66   if (themap.FindIndex(igesent)) return Standard_False;
67   themap.Add(igesent);
68 //  Recuperation de la vue (attention au cas du Drawing)
69   Handle(IGESData_IGESEntity) view;
70   if (igesent->TypeNumber() == PourDrawing) view = igesent;  // DRAWING
71   else {
72     if (igesent->IsKind(STANDARD_TYPE(IGESData_ViewKindEntity))) view = igesent; // VIEW
73     else view = igesent->View();
74 /*
75     DeclareAndCast(IGESData_ViewKindEntity,trueview,view);
76     if (!trueview.IsNull())
77       if (trueview->IsSingle()) view.Nullify();  // Multiple -> Nulle
78 */
79   }
80 //  On enregistre
81   Standard_Integer viewindex = 0;  // 0 sera pour remain
82   if (!view.IsNull()) {
83     viewindex = theitems.FindIndex(view);
84     if (viewindex <= 0) viewindex = theitems.Add(view);
85   }
86   theinditem.Append(viewindex);
87   theindfin.Append(0);
88   return Standard_True;
89 }
90 
91 
AddList(const Handle (TColStd_HSequenceOfTransient)& list)92     void  IGESSelect_ViewSorter::AddList
93   (const Handle(TColStd_HSequenceOfTransient)& list)
94 {
95   Standard_Integer nb = list->Length();
96   for (Standard_Integer i = 1; i <= nb; i ++) Add (list->Value(i));
97 }
98 
AddModel(const Handle (Interface_InterfaceModel)& model)99     void  IGESSelect_ViewSorter::AddModel
100   (const Handle(Interface_InterfaceModel)& model)
101 {
102   DeclareAndCast(IGESData_IGESModel,igesmod,model);
103   if (igesmod.IsNull()) return;
104   Standard_Integer nb = igesmod->NbEntities();
105   for (Standard_Integer i = 1; i <= nb; i ++) AddEntity (igesmod->Entity(i));
106 }
107 
NbEntities() const108     Standard_Integer  IGESSelect_ViewSorter::NbEntities () const
109       {  return themap.Extent();  }
110 
111 //  .....    Attention    .....
112 
SortSingleViews(const Standard_Boolean alsoframes)113     void  IGESSelect_ViewSorter::SortSingleViews
114   (const Standard_Boolean alsoframes)
115 {
116 // Du tas initial, on ecarte : les vues nulles, et selon alsoframe les drawings
117 // Vues nulles : cf theremain (remain initial reconduit)
118 
119 //  Remarque : le filtre IsSingle a ete applique par Add
120   thefinals.Clear();
121   Standard_Integer nb = theinditem.Length();
122   //Standard_Integer numit = 0; //szv#4:S4163:12Mar99 not needed
123   for (Standard_Integer i = 1; i <= nb; i ++) {
124     Standard_Integer numitem = theinditem.Value(i);
125     Standard_Integer finalindex = 0;  // 0 sera pour remain
126     if (numitem > 0) {
127       //numit = numitem; //szv#4:S4163:12Mar99 not needed
128       DeclareAndCast(IGESData_IGESEntity,item,theitems.FindKey(numitem));
129       Standard_Boolean ok = Standard_False;
130       if (alsoframes)  ok = (item->TypeNumber() == PourDrawing);
131       if (!ok) {
132 	DeclareAndCast(IGESData_ViewKindEntity,view,item);
133 	if (!view.IsNull()) ok = view->IsSingle();
134       }
135       if (ok) {
136 	finalindex = thefinals.FindIndex(item);
137 	if (finalindex <= 0) finalindex = thefinals.Add(item);
138       }
139     }
140     theindfin.SetValue(i,finalindex);
141   }
142 }
143 
144 
SortDrawings(const Interface_Graph & G)145     void  IGESSelect_ViewSorter::SortDrawings (const Interface_Graph& G)
146 {
147 // Pour chaque item (vue ou drawing), drawing contenant, silya (sinon tant pis)
148 
149   thefinals.Clear();
150   Standard_Integer nb = theinditem.Length();
151   //Standard_Integer numit = 0; //szv#4:S4163:12Mar99 not needed
152   for (Standard_Integer i = 1; i <= nb; i ++) {
153     Standard_Integer numitem = theinditem.Value(i);
154     Standard_Integer finalindex = 0;  // 0 sera pour remain
155     if (numitem > 0) {
156       //numit = numitem; //szv#4:S4163:12Mar99 not needed
157       DeclareAndCast(IGESData_IGESEntity,item,theitems.FindKey(numitem));
158       if (item.IsNull()) continue;
159 //  Si cest un Drawing, il definit le Set. Sinon, chercher Drawing contenant
160       Handle(Standard_Transient) drawing;
161       if (item->TypeNumber() == PourDrawing) drawing = item;
162       else {
163 	Interface_EntityIterator list = G.Sharings(item);
164 	for (list.Start(); list.More(); list.Next()) {
165 	  DeclareAndCast(IGESData_IGESEntity,draw,list.Value());
166 	  if (draw.IsNull()) continue;
167 	  if (draw->TypeNumber() == PourDrawing) drawing = draw;
168 	}
169       }
170       if (!drawing.IsNull()) {
171 	finalindex = thefinals.FindIndex(drawing);
172 	if (finalindex <= 0) finalindex = thefinals.Add(drawing);
173       }
174     }
175     theindfin.SetValue(i,finalindex);
176   }
177 }
178 
179 //  ....    Queries    ....
180 
NbSets(const Standard_Boolean final) const181     Standard_Integer  IGESSelect_ViewSorter::NbSets
182   (const Standard_Boolean final) const
183 {
184   if (final) return thefinals.Extent();
185   else       return theitems.Extent();
186 }
187 
Handle(IGESData_IGESEntity)188     Handle(IGESData_IGESEntity)  IGESSelect_ViewSorter::SetItem
189   (const Standard_Integer num, const Standard_Boolean final) const
190 {
191   if (final) return GetCasted(IGESData_IGESEntity,thefinals.FindKey(num));
192   else       return GetCasted(IGESData_IGESEntity,theitems.FindKey(num));
193 }
194 
Handle(IFSelect_PacketList)195     Handle(IFSelect_PacketList)  IGESSelect_ViewSorter::Sets
196   (const Standard_Boolean final) const
197 {
198   Handle(IFSelect_PacketList) list = new IFSelect_PacketList(themodel);
199   Standard_Integer i, nb;
200   nb = (final ? theindfin.Length() : theinditem.Length());
201   Standard_Integer nbs = NbSets(final);
202   for (Standard_Integer num = 1; num <= nbs; num ++) {
203     list->AddPacket();
204     if (final) {
205 //    Attention a l unicite
206       for (i = 1; i <= nb; i ++) {
207 	if (theindfin.Value(i) != num) continue;
208 	list->Add (themap.FindKey(i));
209       }
210     } else {
211       for (i = 1; i <= nb; i ++) {
212 	if (theinditem.Value(i) != num) continue;
213 	list->Add (themap.FindKey(i));
214       }
215     }
216   }
217   return list;
218 }
219