27 #include "message-macros.hh"
30 using namespace GMap3d;
34 #define a0 FMap->alpha0
35 #define a1 FMap->alpha1
36 #define a2 FMap->alpha2
37 #define a3 FMap->alpha3
39 #define VTX(d) (AVertexDI < 0 ? FMap->findVertex(d) : \
40 (CAttributeVertex*)FMap->getDirectInfo(d, AVertexDI))
44 CCorefine3dTools::CCorefine3dTools(CGMapVertex * AMap,
53 const CVertex & ASectorVector1,
54 const CVertex & ASectorVector2,
55 const CPlane & APlane,
59 TCoordinate pv = (ASectorVector1 * ASectorVector2).dot(APlane.getNormal());
60 TCoordinate pv1 = (ASectorVector1 * AVector).dot(APlane.getNormal());
61 TCoordinate pv2 = (ASectorVector2 * AVector).dot(APlane.getNormal());
62 bool result = pv < 0.0 ? pv1 >= 0.0 || pv2 <= 0.0 : pv1 >= 0.0 && pv2 <= 0.0;
64 if (!result && AThickVector1 && pv1 >= -FEps &&
65 AVector.dot(ASectorVector1) > 0.0) result =
true;
66 if (!result && AThickVector2 && pv2 <= FEps &&
67 AVector.dot(ASectorVector2) > 0.0) result =
true;
76 const CPlane & APlane,
80 CVertex pt = *
VTX(ASector);
82 if (
a2(ASector) !=
a1(ASector))
85 *
VTX(
a0(ASector)) - pt,
90 *
VTX(
a0(ASector)) - pt,
93 isPointOnLine(*
VTX(
a0(ASector)), pt,
95 isPointOnLine(*
VTX(
a0(
a1(ASector))), pt,
104 const CVertex & AVector2)
106 return CGeneralTools::areVectorsColinear(AVector1, AVector2);
112 const CVertex & ALineVertex1,
113 const CVertex & ALineVertex2)
115 return CGeneralTools::pointParameterOnLine(APoint, ALineVertex1,
123 const CPlane & APlane,
135 while (d != AVertex && best == NULL);
137 if (best == NULL || !FMap->isSameOrbit(best, AVertex, ORBIT_01)) {
139 WARN_BB(
"<findSectorOfVector> Aucun secteur valide sur la face !");
148 const CPlane & APlane1,
149 const CVertex & AVertex2,
150 const CPlane & APlane2)
152 CVertex normal1 = APlane1.getNormal();
153 CVertex normal2 = APlane2.getNormal();
155 normal1 = normalizeVector(normal1);
156 normal2 = normalizeVector(normal2);
158 return (isVectorNull(normal1 * normal2) &&
159 isPointOnPlane(AVertex2, APlane1) &&
160 isPointOnPlane(AVertex1, APlane2));
167 TCoordinate n1[4], n2[4];
171 if ((n1[3] < 0.0 && n2[3] < 0.0) ||
172 (n1[3] > 0.0 && n2[3] > 0.0)) {
176 CBoundingBox bb1, bb2;
178 bb1 = orbitBoundingBox(AVertex, ORBIT_VOLUME, AVertexDI);
179 bb2 = orbitBoundingBox(
a3(AVertex), ORBIT_VOLUME, AVertexDI);
181 if (bb1.getSurface() <= bb2.getSurface()) {
184 AVertex =
a1(AVertex);
190 AVertex =
a1(AVertex);
194 else if (n1[3] < 0.0) {
195 AVertex =
a1(AVertex);
205 const CVertex & ALinePoint2,
206 const CVertex & AEdgePoint1,
207 const CVertex & AEdgePoint2,
208 TCoordinate * ALineParam,
209 TCoordinate * AEdgeParam)
211 assert(AEdgeParam != NULL && ALineParam != NULL);
228 if (sqrt(squareDistanceBetweenLines(ALinePoint1, ALinePoint2,
229 AEdgePoint1, AEdgePoint2, &plane)) > FEps)
232 if (isVectorNull(plane.getNormal()))
235 if (!getLinesIntersection(ALinePoint1, ALinePoint2, AEdgePoint1, AEdgePoint2,
236 ALineParam, AEdgeParam, plane))
239 if (*AEdgeParam >= 0.0 && *AEdgeParam <= 1.0)
250 const CPlane & APlane,
251 TCoordinate * AEdgeParam)
253 assert(AEdgeParam != NULL);
255 CVertex v = AEdgePoint2 - AEdgePoint1;
257 if (isPointOnPlane(AEdgePoint2, APlane)) {
262 if (isPointOnPlane(AEdgePoint1, APlane)) {
267 if (!APlane.getLineIntersection(AEdgePoint1, v, AEdgeParam))
274 if (*AEdgeParam >= 0.0 && *AEdgeParam <= 1.0)
284 const CVertex & ADirection,
286 const CPlane & APlane,
292 TProjection proj = APlane.getBestProjection();
294 CVertex projOrigin = APlane.projectPoint(AOrigin, proj);
295 CVertex projDirection = APlane.projectPoint(ADirection, proj);
300 int edge_mark = FMap->getNewMark();
301 TCoordinate t1 = 0.0, t2 = 0.0;
302 CVertex pt1, pt2, pt3;
303 CVertex extremity = projOrigin + projDirection;
305 if (projOrigin != extremity) {
306 MSG(
"Parcours des sommets de la face");
308 pt1 = APlane.projectPoint(*
VTX(d), proj);
310 if (CCorefine2dTools::isPointOnLine(pt1, projOrigin, extremity)) {
311 if (!AExcludeOrigin || !arePointsEqual(projOrigin, pt1)) {
323 MSG(
"une intersection trouvée :" << endl << inter);
328 FMap->setMark(d, edge_mark);
329 FMap->setMark(
a0(d), edge_mark);
330 FMap->setMark(
a1(d), edge_mark);
331 FMap->setMark(
a0(
a1(d)), edge_mark);
338 MSG(
"Parcours des arêtes de la face");
340 pt1 = APlane.projectPoint(*
VTX(d), proj);
341 pt2 = APlane.projectPoint(*
VTX(
a0(d)), proj);
343 if (FMap->isMarked(d, edge_mark)) {
344 FMap->unsetMark(d, edge_mark);
345 FMap->unsetMark(
a0(d), edge_mark);
347 else if (fabs((pt2 - pt1).norm()) > FEps / 2.0 &&
349 !CCorefine2dTools::isPointOnLine(projOrigin, pt1, pt2))) {
365 MSG(
"une intersection trouvée :" << endl << inter);
377 FMap->freeMark(edge_mark);
388 const CVertex & ADirection,
390 const CPlane & AFacePlane,
391 const CPlane & ACutPlane,
400 CVertex pt1, pt2, pt3, dir, extremity = AOrigin + ADirection;
402 int pos_mark = FMap->getNewMark();
403 int neg_mark = FMap->getNewMark();
404 int face_mark = FMap->getNewMark();
406 FMap->markOrbit(AFace, ORBIT_01, face_mark);
408 MSG(
"Parcours des sommets de la face");
411 MSG(
"sommet testé : " << pt1);
412 dist = ACutPlane.pointDistance(pt1);
414 MSG(
"le sommet se trouve du côté négatif");
415 for (CDynamicCoverageVertex dcv(FMap, d); dcv.cont(); ++dcv)
416 if (FMap->isMarked(*dcv, face_mark)) FMap->setMark(*dcv, neg_mark);
418 else if (dist > FEps) {
419 MSG(
"le sommet se trouve du côté positif");
420 for (CDynamicCoverageVertex dcv(FMap, d); dcv.cont(); ++dcv)
421 if (FMap->isMarked(*dcv, face_mark)) FMap->setMark(*dcv, pos_mark);
423 else if (!AExcludeOrigin || !arePointsEqual(pt1, AOrigin)) {
426 MSG(
"le sommet se trouve sur la ligne de coupe");
434 d = FMap->alpha01(d);
438 MSG(
"Parcours des arêtes de la face");
442 MSG(
"arête testée : [" << pt1 <<
";" << pt2 <<
"]");
444 if ((FMap->isMarked(d, pos_mark) && FMap->isMarked(
a0(d), neg_mark)) ||
445 (FMap->isMarked(d, neg_mark) && FMap->isMarked(
a0(d), pos_mark))) {
446 if (!AExcludeOrigin ||
447 !(abs(CPlane(AFacePlane.getNormal() * (pt2-pt1), pt1).
448 pointDistance(AOrigin)) <= FEps)) {
449 if (ACutPlane.getLineIntersection(pt1, dir, &t)) {
450 assert(t > 0.0 && t < 1.0);
454 MSG(
"la ligne de coupe intersecte l'arête en " << pt3);
466 FMap->unsetMark(d, face_mark);
467 FMap->unsetMark(
a0(d), face_mark);
468 for (CDynamicCoverageEdge dce(FMap, d); dce.cont(); ++dce) {
469 FMap->unsetMark(*dce, pos_mark);
470 FMap->unsetMark(*dce, neg_mark);
472 d = FMap->alpha01(d);
479 FMap->freeMark(pos_mark);
480 FMap->freeMark(neg_mark);
481 FMap->freeMark(face_mark);
490 const CVertex & ADirection,
491 CDart * ADart, TOrbit AOrbit,
495 TCoordinate t1 = 0.0, t2 = 0.0;
496 CVertex *pt1, *pt2, pt, extremity = AOrigin + ADirection;
499 int mark = FMap->getNewMark();
500 int edge_mark = FMap->getNewMark();
501 int face_mark = FMap->getNewMark();
502 int orient_mark = FMap->getNewMark();
504 TOrbit orbit_vertex = AND_ORBIT(ORBIT_VERTEX, AOrbit);
505 TOrbit orbit_edge = AND_ORBIT(ORBIT_EDGE, AOrbit);
506 TOrbit orbit_face = AND_ORBIT(ORBIT_FACE, AOrbit);
508 CCoverage *cov = FMap->getDynamicCoverage(ADart, AOrbit);
509 CCoverage *dcf, *tmp_cov;
511 FMap->halfMarkOrbit(ADart, AOrbit, orient_mark);
516 for (cov->reinit(); cov->cont(); ++(*cov)) {
517 dcf = FMap->getDynamicCoverage(**cov, orbit_face);
519 for (; dcf->cont(); ++(*dcf)) {
520 if (!FMap->isMarked(**dcf, mark) && FMap->isMarked(**dcf, orient_mark)) {
522 FMap->markOrbit(**dcf, orbit_vertex, mark);
526 if (isPointOnLine(pt, AOrigin, extremity)) {
537 tmp_cov = FMap->getDynamicCoverage(**dcf, orbit_vertex);
539 for (; tmp_cov->cont(); ++(*tmp_cov)) {
541 if (!FMap->isMarked(**tmp_cov, edge_mark))
542 FMap->markOrbit(**tmp_cov, orbit_edge, edge_mark);
545 if (!FMap->isMarked(**tmp_cov, face_mark))
546 FMap->markOrbit(**tmp_cov, orbit_face, face_mark);
559 for (cov->reinit(); cov->cont(); ++(*cov)) {
560 dcf = FMap->getDynamicCoverage(**cov, orbit_face);
562 for (; dcf->cont(); ++(*dcf)) {
563 if (FMap->isMarked(**dcf, edge_mark)) {
564 FMap->unmarkOrbit(**dcf, orbit_edge, edge_mark);
565 FMap->unmarkOrbit(**dcf, orbit_edge, mark);
567 else if (FMap->isMarked(**dcf, mark) &&
568 FMap->isMarked(**dcf, orient_mark)) {
569 FMap->unmarkOrbit(**dcf, orbit_edge, mark);
572 pt2 =
VTX(
a0(**dcf));
574 if (sqrt(squareDistanceBetweenLines(*pt1, *pt2, AOrigin, extremity,
577 if (!isVectorNull(plane.getNormal()) &&
578 getLinesIntersection(*pt1, *pt2, AOrigin, extremity,
581 pt = AOrigin + t2 * ADirection;
583 if (t1 >= 0.0 && t1 <= 1.0 && t2 > 0) {
591 tmp_cov = FMap->getDynamicCoverage(**dcf, orbit_edge);
593 for (; tmp_cov->cont(); ++(*tmp_cov)) {
595 if (!FMap->isMarked(**tmp_cov, face_mark))
596 FMap->markOrbit(**tmp_cov, orbit_face, face_mark);
610 for (cov->reinit(); cov->cont(); ++(*cov)) {
611 if (FMap->isMarked(**cov, face_mark)) {
612 FMap->unmarkOrbit(**cov, orbit_face, face_mark);
613 FMap->markOrbit(**cov, orbit_face, mark);
615 else if (!FMap->isMarked(**cov, mark)) {
616 face = (FMap->isMarked(**cov, orient_mark)) ? **cov :
a3(**cov);
617 FMap->markOrbit(face, orbit_face, mark);
619 plane = facePlane(face, AVertexDI);
621 if (plane.getLineIntersection(AOrigin, ADirection, &t2)) {
624 pt = AOrigin + t2 * ADirection;
637 for (cov->reinit(); cov->cont(); ++(*cov)) {
638 FMap->unsetMark(**cov, mark);
639 FMap->unsetMark(**cov, orient_mark);
644 FMap->freeMark(mark);
645 FMap->freeMark(edge_mark);
646 FMap->freeMark(face_mark);
647 FMap->freeMark(orient_mark);
655 const CPlane * APlane,
int AVertexDI)
661 plane = facePlane(AFace, AVertexDI);
665 if (APoint == *
VTX(AFace))
668 CVertex direction = *
VTX(AFace) - APoint;
683 CVertex v = edgeVector(inter.
getCell(), AVertexDI);
684 result = (plane.getNormal() * v).dot(direction) < 0.0;
693 #define LINK(d1, d2) (FMap->setDirectInfo(d1, ALinkDirectInfo, d2), \
694 FMap->setDirectInfo(d2, ALinkDirectInfo, d1), \
695 FMap->setDirectInfo(a0(d1), ALinkDirectInfo, a0(d2)), \
696 FMap->setDirectInfo(a0(d2), ALinkDirectInfo, a0(d1)))
698 #define UNLINK(d) (FMap->setDirectInfo(d, ALinkDirectInfo, NULL), \
699 FMap->setDirectInfo(a0(d), ALinkDirectInfo, NULL))
701 #define ALPHA2(d) ((FMap->getDirectInfo(d, ALinkDirectInfo) != NULL) ? \
702 (CDart*)FMap->getDirectInfo(d, ALinkDirectInfo) : \
710 CPlane plane(edgeVector(AEdge1, AVertexDI), *
VTX(AEdge1));
714 CDart *best, *tmp1, *tmp2;
718 v = faceNormalVector(d1, AVertexDI);
722 v2 = faceNormalVector(d2, AVertexDI);
724 tmp2 =
a3(alpha2(d2));
727 v2 = faceNormalVector(tmp2, AVertexDI);
734 while (d2 != AEdge2 && best == NULL);
737 WARN_BB(
"<sortFacesAroundEdges_Naive> Aucun secteur trouvé !");
745 if (FMap->getDirectInfo(tmp1, ALinkDirectInfo) == d2) {
749 if (FMap->getDirectInfo(d2, ALinkDirectInfo) == NULL)
753 tmp1 = alpha2(
a3(d1));
755 if (FMap->getDirectInfo(tmp1, ALinkDirectInfo) == tmp2) {
759 if (FMap->getDirectInfo(tmp2, ALinkDirectInfo) == NULL)
764 while (d1 != AEdge1);
774 CPlane plane(edgeVector(AEdge1, AVertexDI), *
VTX(AEdge1));
779 int mark = FMap->getNewMark();
781 for (CDynamicCoverageEdge dce1(FMap, AEdge1); dce1.cont(); dce1++)
782 FMap->setDirectInfo(*dce1, ALinkDirectInfo, NULL);
783 for (CDynamicCoverageEdge dce2(FMap, AEdge2); dce2.cont(); dce2++)
784 FMap->setDirectInfo(*dce2, ALinkDirectInfo, NULL);
789 v = faceNormalVector(d1, AVertexDI);
792 v2 = faceNormalVector(d2, AVertexDI);
794 FMap->setMark(d2, mark);
800 v2 = faceNormalVector(tmp, AVertexDI);
807 while (best == NULL && !FMap->isMarked(d2, mark));
809 FMap->unmarkOrbit(AEdge1, ORBIT_23, mark);
810 FMap->unmarkOrbit(AEdge2, ORBIT_23, mark);
813 WARN_BB(
"<sortFacesAroundEdges_NaiveBis> Aucun secteur trouvé !");
832 if (FMap->getDirectInfo(d2, ALinkDirectInfo) != NULL) {
833 tmp = (CDart*)FMap->getDirectInfo(d2, ALinkDirectInfo);
845 while (d1 != AEdge1);
847 FMap->freeMark(mark);
857 int mark = FMap->getNewMark();
859 CPlane plane(edgeVector(AEdge1, AVertexDI), *
VTX(AEdge1));
862 CVertex v = faceNormalVector(d, AVertexDI);
864 CDart *tmp =
a3(alpha2(AEdge2));
865 CVertex v1 = faceNormalVector(AEdge2, AVertexDI);
866 CVertex v2 = faceNormalVector(tmp, AVertexDI);
876 tmp =
a3(alpha2(AEdge2));
877 v2 = faceNormalVector(tmp, AVertexDI);
880 CDart *d1 =
a3(alpha2(AEdge1));
881 CDart *d2 =
a3(alpha2(AEdge2));
883 v1 = faceNormalVector(d1, AVertexDI);
884 v2 = faceNormalVector(d2, AVertexDI);
887 FMap->setMark(d, mark);
890 if (!FMap->isMarked(d2, mark)) {
892 FMap->setMark(d2, mark);
904 v1 = faceNormalVector(d1, AVertexDI);
905 v2 = faceNormalVector(d2, AVertexDI);
914 v2 = faceNormalVector(d2, AVertexDI);
923 v1 = faceNormalVector(d1, AVertexDI);
926 while (!FMap->isMarked(d, mark));
928 bool problem =
false;
933 if (FMap->isMarked(d2, mark))
934 FMap->unsetMark(d2, mark);
936 WARN_BR(
"<sortFacesAroundEdges> Brin de la deuxième arête non marqué !");
942 while (d2 != AEdge2);
947 if (FMap->isMarked(d1, mark))
948 FMap->unsetMark(d1, mark);
950 WARN_BR(
"<sortFacesAroundEdges> Brin de la première arête non marqué !");
956 while (d1 != AEdge1);
958 FMap->freeMark(mark);
963 FMap->setDirectInfo(d1, ALinkDirectInfo, NULL);
966 while (d1 != AEdge1);
970 FMap->setDirectInfo(d2, ALinkDirectInfo, NULL);
973 while (d2 != AEdge2);
986 : FTools(ATools), FAxis(AAxis), FVertexDI(AVertexDI) {}
988 bool operator () (CDart * AFace1, CDart * AFace2)
990 CVertex v1 = FTools.faceNormalVector(AFace1, FVertexDI);
991 CVertex v2 = FTools.faceNormalVector(AFace2, FVertexDI);
992 return (v1 * v2).dot(FAxis) > 0.0;
1005 int ALinkDirectInfo,
1009 CVertex axis = edgeVector(AEdge1, AVertexDI);
1011 multiset<CDart*, CFaceComparator> faces(comp);
1012 multiset<CDart*, CFaceComparator>::iterator it, tmp_it;
1014 for (CDynamicCoverageEdge dce1(FMap, AEdge1); dce1.cont(); ++dce1)
1015 FMap->setDirectInfo(*dce1, ALinkDirectInfo, NULL);
1016 for (CDynamicCoverageEdge dce2(FMap, AEdge2); dce2.cont(); ++dce2)
1017 FMap->setDirectInfo(*dce2, ALinkDirectInfo, NULL);
1022 d1 =
a3(alpha2(d1));
1024 while (d1 != AEdge1);
1029 d2 =
a3(alpha2(d2));
1031 while (d2 != AEdge2);
1033 for (it = faces.begin(); it != faces.end(); ) {
1037 d2 = (it != faces.end()) ? *it : *faces.begin();
1050 return (AMat[0][0] * (AMat[1][1] * AMat[2][2] - AMat[2][1] * AMat[1][2]) -
1051 AMat[0][1] * (AMat[1][0] * AMat[2][2] - AMat[2][0] * AMat[1][2]) -
1052 AMat[0][2] * (AMat[1][0] * AMat[2][1] - AMat[2][0] * AMat[1][1]));
1058 const CVertex & AV2,
1059 const CVertex & AV3,
1060 TCoordinate ANormal[4])
1062 TCoordinate mat[3][3];
1106 mat[0][0] = AV1.getX();
1107 mat[0][1] = AV1.getY();
1108 mat[0][2] = AV1.getZ();
1110 mat[1][0] = AV2.getX();
1111 mat[1][1] = AV2.getY();
1112 mat[1][2] = AV2.getZ();
1114 mat[2][0] = AV3.getX();
1115 mat[2][1] = AV3.getY();
1116 mat[2][2] = AV3.getZ();
1124 TCoordinate ANormal[4],
1127 int orient_mark = FMap->getNewMark();
1131 ANormal[0] = ANormal[1] = ANormal[2] = ANormal[3] = 0.0;
1133 FMap->halfMarkOrbit(AVolume, ORBIT_VOLUME, orient_mark);
1135 for (CDynamicCoverageVolume dcv(FMap, AVolume); dcv.cont(); dcv++) {
1136 if (FMap->isMarked(*dcv, orient_mark)) {
1137 FMap->unsetMark(*dcv, orient_mark);
1139 if (!FMap->isFree2(*dcv)) {
1140 v1 = edgeVector(
a1(
a2(*dcv)), AVertexDI);
1141 v2 = edgeVector(*dcv, AVertexDI);
1142 v3 = edgeVector(
a1(*dcv), AVertexDI);
1148 ANormal[3] += tmp[3];
1153 FMap->freeMark(orient_mark);