Skip to content

Commit 7859946

Browse files
authored
Merge pull request #151 from LIHPC-Computational-Geometry/issue#208
Issue#208
2 parents c46264a + e7dd41f commit 7859946

15 files changed

+300
-110
lines changed

src/Core/Geom/CommandEditGeom.cpp

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,36 +45,18 @@ void CommandEditGeom::internalExecute()
4545
internalSpecificPreExecute();
4646

4747
// on recupere toutes les entites concernes par l'opération géométrique
48-
std::map<GeomEntity*,MementoEntity> ref;
49-
std::vector<std::list<GeomEntity*>*> refEntities;
48+
std::map<GeomEntity*, MementoEntity> mementos_by_entity;
49+
std::set<GeomEntity*> to_mem_entities[4];
5050

51-
refEntities.push_back(&(getRefEntities(0))); //sommets
52-
refEntities.push_back(&(getRefEntities(1))); //courbes
53-
refEntities.push_back(&(getRefEntities(2))); //surfaces
54-
refEntities.push_back(&(getRefEntities(3))); //volumes
55-
56-
// MODIF - LES ENTITES ADJ NE SONT PAS DES ENTITES DE REF
57-
// refEntities[0]->insert(refEntities[0]->begin(),getAdjEntities(0).begin(),getAdjEntities(0).end());
58-
// refEntities[1]->insert(refEntities[1]->begin(),getAdjEntities(1).begin(),getAdjEntities(1).end());
59-
// refEntities[2]->insert(refEntities[2]->begin(),getAdjEntities(2).begin(),getAdjEntities(2).end());
60-
// refEntities[3]->insert(refEntities[3]->begin(),getAdjEntities(3).begin(),getAdjEntities(3).end());
61-
62-
#ifdef _DEBUG2
63-
std::cerr<<"nb refs sommets = "<<getRefEntities(0).size()<<std::endl;
64-
std::cerr<<"nb refs curves = "<<getRefEntities(1).size()<<std::endl;
65-
std::cerr<<"nb refs surfaces= "<<getRefEntities(2).size()<<std::endl;
66-
std::cerr<<"nb refs volumes = "<<getRefEntities(3).size()<<std::endl;
67-
#endif
68-
for(unsigned int i=0;i<4;i++){
69-
std::list<GeomEntity*>* refList = refEntities[i];
70-
std::list<GeomEntity*>::iterator it;
71-
for(it=refList->begin();it!=refList->end();it++){
72-
GeomEntity* e = *it;
51+
for(unsigned int i=0;i<4;i++) {
52+
to_mem_entities[i].insert(getRefEntities(i).begin(), getRefEntities(i).end());
53+
to_mem_entities[i].insert(getAdjEntities(i).begin(), getAdjEntities(i).end());
54+
for (GeomEntity* e : to_mem_entities[i]) {
7355
MementoEntity mem = m_memento_manager.createMemento(e);
7456
#ifdef _DEBUG2
7557
std::cerr<<"Memento cree pour "<<e->getName()<<std::endl;
7658
#endif
77-
ref.insert({e, mem});
59+
mementos_by_entity.insert({e, mem});
7860
}
7961
}
8062
// gmds::Timer t2;
@@ -134,19 +116,27 @@ void CommandEditGeom::internalExecute()
134116
}
135117
#endif
136118

137-
//sauvegarde des mementos pour le undo/redo
119+
// Sauvegarde des mementos pour le undo/redo
120+
// Utiliser at en lecture pour avoir une exception si
121+
// la clef est absente (ne pas utiliser l'opérateur [])
138122
std::map<GeomEntity*,MementoEntity> keeped_ref;
139123
for(unsigned int i=0;i<mod_entities.size();i++){
140124
GeomEntity* e = mod_entities[i];
141-
keeped_ref[e] = ref[e];
125+
if (mementos_by_entity.find(e) == mementos_by_entity.end())
126+
std::cout << "*** MOD les mementos ne contiennent pas " << e->getName() << std::endl;
127+
keeped_ref[e] = mementos_by_entity.at(e);
142128
}
143129
for(unsigned int i=0;i<mov_entities.size();i++){
144130
GeomEntity* e = mov_entities[i];
145-
keeped_ref[e] = ref[e];
131+
if (mementos_by_entity.find(e) == mementos_by_entity.end())
132+
std::cout << "*** MOV les mementos ne contiennent pas " << e->getName() << std::endl;
133+
keeped_ref[e] = mementos_by_entity.at(e);
146134
}
147135
for(unsigned int i=0;i<rem_entities.size();i++){
148136
GeomEntity* e = rem_entities[i];
149-
keeped_ref[e] = ref[e];
137+
if (mementos_by_entity.find(e) == mementos_by_entity.end())
138+
std::cout << "*** REM les mementos ne contiennent pas " << e->getName() << std::endl;
139+
keeped_ref[e] = mementos_by_entity.at(e);
150140
}
151141
saveMementos(keeped_ref);
152142
getInfoCommand().setDestroyAndUpdateConnectivity(rem_entities);

src/Core/Geom/CommandJoinEntities.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ std::list<GeomEntity*>& CommandJoinEntities::getRefEntities(const int dim)
9090
return m_ref_entities[dim];
9191
}
9292
/*----------------------------------------------------------------------------*/
93+
std::list<GeomEntity*>& CommandJoinEntities::getAdjEntities(const int dim)
94+
{
95+
return m_adj_entities[dim];
96+
}
97+
/*----------------------------------------------------------------------------*/
9398
std::map<GeomEntity*,std::vector<GeomEntity*> >& CommandJoinEntities::getReplacedEntities()
9499
{
95100
return m_replacedEntities;

src/Core/Geom/GeomEntity.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ getRepresentation(Utils::DisplayRepresentation& dr, bool checkDestroyed) const
9999
template<typename T>
100100
void GeomEntity::
101101
buildSerializedRepresentation(Utils::SerializedRepresentation& description, const std::string& title,
102-
const std::set<T*, decltype(&Utils::Entity::compareEntity)> elements) const
102+
const Utils::EntitySet<T*> elements) const
103103
{
104104
if (!elements.empty()){
105105
Utils::SerializedRepresentation sr (title,TkUtil::NumericConversions::toStr(elements.size()));

src/Core/Geom/GeomModificationBaseClass.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,20 @@ void GeomModificationBaseClass::init(std::vector<GeomEntity*>& es)
6969
{
7070
// pour chacune des entités passées en argument, on ajoute les entités de
7171
// dimension inférieure et supérieure ou égale en référence.
72-
for(unsigned int i=0;i<es.size();i++){
73-
GeomEntity* esi = es[i];
72+
for(GeomEntity* esi : es){
7473
m_init_entities.push_back(esi);
7574
addReference(esi);
7675
addDownIncidentReference(esi);
7776
addUpIncidentReference(esi);
7877
}
7978

80-
for(unsigned int i=0;i<es.size();i++){
81-
GeomEntity* esi = es[i];
82-
addAdjacencyReference(esi);
83-
}
79+
for(int i=0 ; i<4 ; i++)
80+
for(GeomEntity* esi : m_ref_entities[i])
81+
addAdjacencyReference(esi);
8482

8583
// une entité a pu être ajoutée plusieurs fois, on élimine maintenant les
8684
// occurrences multiples
87-
for(int i=0;i<4;i++){
85+
for(int i=0 ; i<4 ; i++){
8886
m_ref_entities[i].sort(Utils::Entity::compareEntity);
8987
m_ref_entities[i].unique();
9088
m_adj_entities[i].sort(Utils::Entity::compareEntity);
@@ -165,8 +163,28 @@ addAdjacencyReference(GeomEntity* e)
165163
for (auto ei : va.get())
166164
{
167165
int dim = ei->getDim();
168-
if (dim > 0 && std::find(m_ref_entities[dim].begin(),m_ref_entities[dim].end(),ei)==m_ref_entities[dim].end())
166+
auto& ref = m_ref_entities[dim];
167+
if (std::find(ref.begin(), ref.end(), ei) == ref.end()) {
169168
m_adj_entities[dim].push_back(ei);
169+
170+
// issue#208 : split d'un volume Vol0 à gauche collé (glue) à un volume Vol1 à droite
171+
// la surface Surf0007 de droite de Vol1 n'est pas adjacente à Vol0 mais ses relations
172+
// géométriques vont être changées car elle est adjacente à des surfaces
173+
// qui vont être recréées (changement nb arêtes et shape OCC).
174+
// Il faut donc que Surf0007 soit prise en compte par les mementos en cas de undo
175+
// => on garde les objets "down incident" aux objets adjacents car Surf0007 est
176+
// "down incidente" de Vol1.
177+
GetDownIncidentGeomEntitiesVisitor v_down;
178+
ei->accept(v_down);
179+
for (auto e_down : v_down.get())
180+
{
181+
int dim_down = e_down->getDim();
182+
auto& ref_down = m_ref_entities[dim_down];
183+
if (std::find(ref_down.begin(), ref_down.end(), e_down) == ref_down.end()) {
184+
m_adj_entities[dim_down].push_back(e_down);
185+
}
186+
}
187+
}
170188
}
171189
}
172190
/*----------------------------------------------------------------------------*/
@@ -598,13 +616,6 @@ createGeomEntities(const TopoDS_Shape& shape, const bool replaceVolumes, const b
598616
//===================================================================
599617
rebuildAdjacencyEntities(shape);
600618

601-
602-
// std::vector<Volume*>::iterator it_vKeep = m_toKeepVolumes.begin();
603-
// while(it_vKeep!=m_toKeepVolumes.end()){
604-
// Volume* v = *it_vKeep;
605-
// std::cout<<"\t keep "<<v->getName()<<std::endl;
606-
// it_vKeep++;
607-
// }
608619
std::vector<GeomEntity*>::iterator it_rem = m_removedEntities.begin();
609620
std::vector<GeomEntity*> toErase;
610621
while(it_rem!=m_removedEntities.end()){
@@ -2048,7 +2059,7 @@ void GeomModificationBaseClass::createNewSurfaces(
20482059
#endif
20492060
}
20502061

2051-
} // end for i
2062+
}
20522063

20532064
}
20542065
/*----------------------------------------------------------------------------*/
@@ -2217,6 +2228,8 @@ void GeomModificationBaseClass::createNewAdjVolumes(
22172228
to_keep = true;
22182229
newVolume = current;
22192230
newOCCVolume = V;
2231+
// il faut mettre à jour la OCC shape en cas de non conformité d'une face (issue#208)
2232+
newVolume->m_occ_shape = V;
22202233
m_toKeepVolumes.push_back(current);
22212234
#ifdef _DEBUG2
22222235
std::cout<<"=*= VOLUME ADJ CONSERVE "<<newVolume->getName()<<std::endl;

src/Core/Geom/GeomSectionByPlaneImplementation.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -86,26 +86,35 @@ void GeomSectionByPlaneImplementation::splitEntities(std::vector<GeomEntity*>& r
8686
#ifdef _DEBUG2
8787
std::cout<<"m_init_entities.size = "<<m_init_entities.size()<<std::endl;
8888
#endif
89-
GeomEntity* e1 = m_init_entities[0];
90-
TopoDS_Shape s_fuse;
91-
getUniqueOCCShape(e1, s_fuse);
92-
for(unsigned int i=1;i<m_init_entities.size();i++){
93-
GeomEntity* e2 = m_init_entities[i];
94-
TopoDS_Shape s2;
95-
getUniqueOCCShape(e2, s2);
89+
bool all_volumes = std::all_of(m_init_entities.begin(), m_init_entities.end(), [](GeomEntity* x) {
90+
return (x->getDim() == 3);
91+
});
9692

97-
BRepAlgoAPI_Fuse fuse_operator(s_fuse,s2);
98-
if(fuse_operator.IsDone())
99-
s_fuse = fuse_operator.Shape();
93+
if (all_volumes) {
94+
GeomEntity* e1 = m_init_entities[0];
95+
TopoDS_Shape s_fuse;
96+
getUniqueOCCShape(e1, s_fuse);
97+
for(unsigned int i=1;i<m_init_entities.size();i++){
98+
GeomEntity* e2 = m_init_entities[i];
99+
TopoDS_Shape s2;
100+
getUniqueOCCShape(e2, s2);
101+
102+
BRepAlgoAPI_Fuse fuse_operator(s_fuse,s2);
103+
if(fuse_operator.IsDone())
104+
s_fuse = fuse_operator.Shape();
105+
else
106+
throw TkUtil::Exception (TkUtil::UTF8String ("Problème OCC lors de l'union avant coupe", TkUtil::Charset::UTF_8));
107+
}
108+
// On recupere l'intersection de la surface wf et de l'union des entites à couper
109+
BRepAlgoAPI_Common common_operator(s_fuse, wf);
110+
if(common_operator.IsDone())
111+
m_restricted_section_tool = common_operator.Shape();
100112
else
101-
throw TkUtil::Exception (TkUtil::UTF8String ("Problème OCC lors de l'union avant coupe", TkUtil::Charset::UTF_8));
113+
throw TkUtil::Exception (TkUtil::UTF8String ("Problème OCC lors de l'intersection avant coupe", TkUtil::Charset::UTF_8));
114+
} else {
115+
// les opérations fuse + common ne fonctionnent pas s'il y a une surface
116+
m_restricted_section_tool = wf;
102117
}
103-
// On recupere l'intersection de la surface wf et de l'union des entites à couper
104-
BRepAlgoAPI_Common common_operator(s_fuse,wf);
105-
if(common_operator.IsDone())
106-
m_restricted_section_tool = common_operator.Shape();
107-
else
108-
throw TkUtil::Exception (TkUtil::UTF8String ("Problème OCC lors de l'intersection avant coupe", TkUtil::Charset::UTF_8));
109118

110119
//========================================================================
111120
// 3 - Decoupe des entités
@@ -120,7 +129,7 @@ void GeomSectionByPlaneImplementation::splitEntities(std::vector<GeomEntity*>& r
120129
getUniqueOCCShape(ei, si);
121130
list_of_arguments.Append(si);
122131
}
123-
list_of_arguments.Append(wf);
132+
list_of_arguments.Append(m_restricted_section_tool);
124133
splitter.SetArguments(list_of_arguments);
125134
splitter.Build();
126135

@@ -138,9 +147,7 @@ void GeomSectionByPlaneImplementation::splitEntities(std::vector<GeomEntity*>& r
138147
rep_ei.push_back(m_newVolumes[j]);
139148
}
140149

141-
// res.insert(res.end(),new_volumes.begin(),new_volumes.end());
142-
143-
res.insert(res.end(), entities_new.begin(), entities_new.end());
150+
res.insert(res.end(), m_newEntities.begin(), m_newEntities.end());
144151
}
145152
/*----------------------------------------------------------------------------*/
146153
std::vector<GeomEntity*> GeomSectionByPlaneImplementation::getEntitiesOnPlane()

src/Core/Geom/OCCHelper.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include <ShapeFix_Wireframe.hxx>
3535
#include <ShapeFix_FixSmallFace.hxx>
3636
#include <ShapeBuild_ReShape.hxx>
37-
37+
#include <ShapeAnalysis_ShapeContents.hxx>
3838
/*----------------------------------------------------------------------------*/
3939
namespace Mgx3D {
4040
/*----------------------------------------------------------------------------*/
@@ -1336,6 +1336,54 @@ addShapeToLists(TopoDS_Shape& shape,
13361336

13371337
}
13381338
/*----------------------------------------------------------------------------*/
1339+
void OCCHelper::
1340+
printInfos(const TopoDS_Shape& shape, const std::string& indent)
1341+
{
1342+
std::cout << indent << "Shape de type ";
1343+
TopAbs_ShapeEnum type = shape.ShapeType();
1344+
switch (type) {
1345+
case TopAbs_COMPOUND: std::cout << "Compound"; break;
1346+
case TopAbs_COMPSOLID: std::cout << "CompSolid"; break;
1347+
case TopAbs_SOLID: std::cout << "Solid"; break;
1348+
case TopAbs_SHELL: std::cout << "Shell"; break;
1349+
case TopAbs_FACE: std::cout << "Face"; break;
1350+
case TopAbs_WIRE: std::cout << "Wire"; break;
1351+
case TopAbs_EDGE: std::cout << "Edge"; break;
1352+
case TopAbs_VERTEX: std::cout << "Vertex"; break;
1353+
case TopAbs_SHAPE: std::cout << "Generic Shape"; break;
1354+
}
1355+
std::cout << " : " << std::endl;
1356+
1357+
ShapeAnalysis_ShapeContents analysis;
1358+
analysis.Perform(shape);
1359+
std::cout << indent << "\tNb solids : " << analysis.NbSolids() << std::endl;
1360+
std::cout << indent << "\tNb faces : " << analysis.NbFaces() << std::endl;
1361+
1362+
if (type == TopAbs_COMPOUND) {
1363+
std::cout << indent << "\tDétails du compound :" << std::endl;
1364+
exploreCompound(TopoDS::Compound(shape), indent);
1365+
}
1366+
}
1367+
/*----------------------------------------------------------------------------*/
1368+
void OCCHelper::
1369+
printInfos(const TopTools_ListOfShape& shapes)
1370+
{
1371+
for (TopTools_ListIteratorOfListOfShape it(shapes); it.More(); it.Next()) {
1372+
TopoDS_Shape shape = it.Value();
1373+
printInfos(shape);
1374+
}
1375+
}
1376+
/*----------------------------------------------------------------------------*/
1377+
void OCCHelper::
1378+
exploreCompound(const TopoDS_Compound& compound, const std::string& indent)
1379+
{
1380+
std::string new_indent = indent + "\t";
1381+
for (TopExp_Explorer exp(compound, TopAbs_SOLID); exp.More(); exp.Next()) {
1382+
TopoDS_Shape sub_shape = exp.Current();
1383+
printInfos(sub_shape, new_indent);
1384+
}
1385+
}
1386+
/*----------------------------------------------------------------------------*/
13391387
} // end namespace Geom
13401388
/*----------------------------------------------------------------------------*/
13411389
} // end namespace Mgx3D

src/Core/Topo/CoEdge.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ replace(Topo::Vertex* v1, Topo::Vertex* v2, bool propagate_up, bool propagate_do
157157

158158
// transmet aux Edges
159159
if (propagate_up)
160+
/*
161+
* 9/7/2025 ** ATTENTION **
162+
* Ne pas passer en "modern C++ loop" : for (Edge* e : getEdges())
163+
* car Edge::replace appelle Edge::free qui modifie la liste
164+
* des edges de la coedge ce qui perturbe le parcours de la boucle.
165+
*/
160166
for (uint j=0; j<getNbEdges(); j++)
161167
getEdge(j)->replace(v1, v2, propagate_up, propagate_down, icmd);
162168

src/Core/protected/Geom/CommandJoinEntities.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class CommandJoinEntities: public CommandEditGeom
7272
* l'algorithme travaille
7373
*/
7474
virtual std::list<GeomEntity*>& getRefEntities(const int dim);
75+
virtual std::list<GeomEntity*>& getAdjEntities(const int dim);
7576

7677
/*------------------------------------------------------------------------*/
7778
/** \brief retourne une référence sur une map indiquant par quelles
@@ -119,6 +120,8 @@ class CommandJoinEntities: public CommandEditGeom
119120

120121
/// référence sur toutes les entités sur lesquelles l'algorithme travaille
121122
std::list<GeomEntity*> m_ref_entities[4];
123+
/// liste inutilisée : juste pour répondre à la méthode get de la classe mère
124+
std::list<GeomEntity*> m_adj_entities[4];
122125

123126
/* entités que l'on a conservées (modifiées ou non)*/
124127
std::vector<Vertex*> m_toKeepVertices;

src/Core/protected/Geom/GeomEntity.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class GeomEntity : public Internal::InternalEntity{
169169
#ifndef SWIG
170170
template<typename T>
171171
void buildSerializedRepresentation(Utils::SerializedRepresentation& description, const std::string& title,
172-
const std::set<T*, decltype(&Utils::Entity::compareEntity)> elements) const;
172+
const Utils::EntitySet<T*> elements) const;
173173
#endif
174174

175175
private:

0 commit comments

Comments
 (0)