1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0030804: Foundation Classes - Poly_Connect crashes due to out-of-range array modification

Fixed initialization of edges array based on the wrong statement.
This commit is contained in:
kgv 2019-06-25 19:39:49 +03:00 committed by apn
parent 95bde2af7f
commit 841aa8c47b
2 changed files with 98 additions and 87 deletions

View File

@ -76,13 +76,13 @@ void Poly_Connect::Load (const Handle(Poly_Triangulation)& theTriangulation)
mysense = false; mysense = false;
mymore = false; mymore = false;
const Standard_Integer nbNodes = myTriangulation->NbNodes(); const Standard_Integer aNbNodes = myTriangulation->NbNodes();
const Standard_Integer nbTriangles = myTriangulation->NbTriangles(); const Standard_Integer aNbTris = myTriangulation->NbTriangles();
{ {
const Standard_Integer aNbAdjs = 6 * nbTriangles; const Standard_Integer aNbAdjs = 6 * aNbTris;
if (myTriangles.Size() != nbNodes) if (myTriangles.Size() != aNbNodes)
{ {
myTriangles.Resize (1, nbNodes, Standard_False); myTriangles.Resize (1, aNbNodes, Standard_False);
} }
if (myAdjacents.Size() != aNbAdjs) if (myAdjacents.Size() != aNbAdjs)
{ {
@ -95,118 +95,117 @@ void Poly_Connect::Load (const Handle(Poly_Triangulation)& theTriangulation)
// We first build an array of the list of edges connected to the nodes // We first build an array of the list of edges connected to the nodes
// create an array to store the edges starting from the vertices // create an array to store the edges starting from the vertices
Standard_Integer i; NCollection_Array1<polyedge*> anEdges (1, aNbNodes);
// the last node is not used because edges are stored at the lower node index anEdges.Init (NULL);
polyedge** edges = new polyedge*[nbNodes];
for (i = 0; i < nbNodes; i++) edges[i] = 0;
// loop on the triangles // loop on the triangles
Standard_Integer j,k,n[3],n1,n2; NCollection_Vec3<Standard_Integer> aTriNodes;
const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles(); NCollection_Vec2<Standard_Integer> anEdgeNodes;
for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
for (i = 1; i <= nbTriangles; i++) { {
// get the nodes // get the nodes
triangles(i).Get(n[0],n[1],n[2]); myTriangulation->Triangle (aTriIter).Get (aTriNodes[0], aTriNodes[1], aTriNodes[2]);
// Update the myTriangles array // Update the myTriangles array
myTriangles(n[0]) = i; myTriangles.SetValue (aTriNodes[0], aTriIter);
myTriangles(n[1]) = i; myTriangles.SetValue (aTriNodes[1], aTriIter);
myTriangles(n[2]) = i; myTriangles.SetValue (aTriNodes[2], aTriIter);
// update the edge lists // update the edge lists
for (j = 0; j < 3; j++) { for (Standard_Integer aNodeInTri = 0; aNodeInTri < 3; ++aNodeInTri)
k = (j+1) % 3; // the following node of the edge {
if (n[j] <= n[k]) { const Standard_Integer aNodeNext = (aNodeInTri + 1) % 3; // the following node of the edge
n1 = n[j]; if (aTriNodes[aNodeInTri] < aTriNodes[aNodeNext])
n2 = n[k]; {
anEdgeNodes[0] = aTriNodes[aNodeInTri];
anEdgeNodes[1] = aTriNodes[aNodeNext];
} }
else { else
n1 = n[k]; {
n2 = n[j]; anEdgeNodes[0] = aTriNodes[aNodeNext];
anEdgeNodes[1] = aTriNodes[aNodeInTri];
} }
// edge from n1 to n2 with n1 < n2 // edge from node 0 to node 1 with node 0 < node 1
// insert in the list of n1 // insert in the list of node 0
polyedge* ced = anEdges[anEdgeNodes[0]];
polyedge* ced = edges[n1]; for (; ced != NULL; ced = ced->next)
while (ced != 0) { {
// the edge already exists // the edge already exists
if (ced->nd == n2) if (ced->nd == anEdgeNodes[1])
break; {
else // just mark the adjacency if found
ced = ced->next; ced->nt[1] = aTriIter;
ced->nn[1] = aTriNodes[3 - aNodeInTri - aNodeNext]; // the third node
break;
}
} }
if (ced == 0) { if (ced == NULL)
// create the edge if not found {
ced = new polyedge; // create the edge if not found
ced->next = edges[n1]; ced = new polyedge();
edges[n1] = ced; ced->next = anEdges[anEdgeNodes[0]];
ced->nd = n2; anEdges[anEdgeNodes[0]] = ced;
ced->nt[0] = i; ced->nd = anEdgeNodes[1];
ced->nn[0] = n[3-j-k]; // the third node ced->nt[0] = aTriIter;
ced->nt[1] = 0; ced->nn[0] = aTriNodes[3 - aNodeInTri - aNodeNext]; // the third node
ced->nn[1] = 0; ced->nt[1] = 0;
} ced->nn[1] = 0;
else {
// just mark the adjacency if found
ced->nt[1] = i;
ced->nn[1] = n[3-j-k]; // the third node
} }
} }
} }
// now complete the myAdjacents array // now complete the myAdjacents array
Standard_Integer anAdjIndex = 1;
Standard_Integer index = 1; for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
for (i = 1; i <= nbTriangles; i++) { {
// get the nodes // get the nodes
triangles(i).Get(n[0],n[1],n[2]); myTriangulation->Triangle (aTriIter).Get (aTriNodes[0], aTriNodes[1], aTriNodes[2]);
// fore each edge // for each edge in triangle
for (j = 0; j < 3; j++) { for (Standard_Integer aNodeInTri = 0; aNodeInTri < 3; ++aNodeInTri)
k = (j+1) % 3; // the following node of the edge {
if (n[j] <= n[k]) { const Standard_Integer aNodeNext = (aNodeInTri + 1) % 3; // the following node of the edge
n1 = n[j]; if (aTriNodes[aNodeInTri] < aTriNodes[aNodeNext])
n2 = n[k]; {
anEdgeNodes[0] = aTriNodes[aNodeInTri];
anEdgeNodes[1] = aTriNodes[aNodeNext];
} }
else { else
n1 = n[k]; {
n2 = n[j]; anEdgeNodes[0] = aTriNodes[aNodeNext];
anEdgeNodes[1] = aTriNodes[aNodeInTri];
} }
// edge from n1 to n2 with n1 < n2 // edge from node 0 to node 1 with node 0 < node 1
// find in the list of n1 // find in the list of node 0
const polyedge* ced = anEdges[anEdgeNodes[0]];
polyedge* ced = edges[n1]; while (ced->nd != anEdgeNodes[1])
while (ced->nd != n2) {
ced = ced->next; ced = ced->next;
}
// Find the adjacent triangle // Find the adjacent triangle
Standard_Integer l = 0; const Standard_Integer l = ced->nt[0] == aTriIter ? 1 : 0;
if (ced->nt[0] == i) l = 1;
myAdjacents.SetValue (anAdjIndex, ced->nt[l]);
myAdjacents(index) = ced->nt[l]; myAdjacents.SetValue (anAdjIndex + 3, ced->nn[l]);
myAdjacents(index+3) = ced->nn[l]; ++anAdjIndex;
index++;
} }
index += 3; anAdjIndex += 3;
} }
// destroy the edges array // destroy the edges array
for (i = 0; i < nbNodes; i++) { for (Standard_Integer aNodeIter = anEdges.Lower(); aNodeIter <= anEdges.Upper(); ++aNodeIter)
polyedge* ced = edges[i]; {
while (ced != 0) { for (polyedge* anEdgeIter = anEdges[aNodeIter]; anEdgeIter != NULL;)
polyedge* tmp = ced->next; {
delete ced; polyedge* aTmp = anEdgeIter->next;
ced = tmp; delete anEdgeIter;
anEdgeIter = aTmp;
} }
} }
delete [] edges;
} }
//======================================================================= //=======================================================================

View File

@ -0,0 +1,12 @@
puts "============"
puts "0030804: Foundation Classes - Poly_Connect crashes due to out-of-range array modification"
puts "============"
pload MODELING VISUALIZATION
restore [locate_data_file bug30804.brep] b
vclear
vinit View1
vdisplay b
vfit
vdump ${imagedir}/${casename}.png