@@ -524,246 +524,6 @@ class BspTree
524524 }
525525 }
526526
527- bool isInside (const point_type & p, const Node * n) const noexcept
528- {
529- coord_type dist = distance (n->plane , p);
530-
531- if (dist < 0 )
532- {
533- if (n->behind )
534- return isInside (p, n->behind .get ());
535- else
536- return true ;
537- }
538- else
539- {
540- if (n->infront )
541- return isInside (p, n->infront .get ());
542- else
543- return false ;
544- }
545- }
546-
547- void reCalculatePlanes (Node * n) noexcept
548- {
549- // recalculate plane for this node with the first triangle on this plane
550- n->plane = calculatePlane (
551- get (n->triangles , 0 ),
552- get (n->triangles , 1 ),
553- get (n->triangles , 2 )
554- );
555-
556- // do the two subtrees
557- if (n->infront ) return reCalculatePlanes (n->infront .get ());
558- if (n->behind ) return reCalculatePlanes (n->behind .get ());
559- }
560-
561- // append vertices
562- void append (C & v, const vertex_type & v1, const vertex_type & v2, const vertex_type & v3) const
563- {
564- container_traits<C>::append (v, v1);
565- container_traits<C>::append (v, v2);
566- container_traits<C>::append (v, v3);
567- }
568-
569- // assumes, that the node is not empty
570- bool classifyTriangle (const Node * n, const vertex_type & v1, const vertex_type & v2, const vertex_type & v3, bool inside, bool keepEdge, C & out, bool keepNow) const
571- {
572- if (!n)
573- {
574- if (keepNow)
575- {
576- append (out, v1, v2, v3);
577- }
578-
579- return keepNow;
580- }
581-
582-
583- // this is again a variation of the code in separateTriangles
584-
585- // calculate distance of the 3 vertices from the choosen partitioning plane
586- std::array<coord_type, 3 > dist
587- {
588- distance (n->plane , vertex_traits<vertex_type>::getPosition (v1)),
589- distance (n->plane , vertex_traits<vertex_type>::getPosition (v2)),
590- distance (n->plane , vertex_traits<vertex_type>::getPosition (v3))
591- };
592-
593- // check on which side of the plane the 3 points are
594- std::array<size_type, 3 > side { sign (dist[0 ]), sign (dist[1 ]), sign (dist[2 ]) };
595-
596- C tmp;
597- std::array<index_type, 3 > A;
598-
599- if (side[0 ] * side[1 ] == -1 )
600- {
601- A[0 ] = container_traits<C>::appendInterpolate (tmp, v1, v2, relation (dist[0 ], dist[1 ]));
602- }
603- if (side[1 ] * side[2 ] == -1 )
604- {
605- A[1 ] = container_traits<C>::appendInterpolate (tmp, v2, v3, relation (dist[1 ], dist[2 ]));
606- }
607- if (side[2 ] * side[0 ] == -1 )
608- {
609- A[2 ] = container_traits<C>::appendInterpolate (tmp, v3, v1, relation (dist[2 ], dist[0 ]));
610- }
611-
612- size_type preAddSize = container_traits<C>::getSize (out);
613- bool complete = true ; // is the triangle completely added with all parts that it is split into
614- bool clipped = true ; // is the triangle split at all
615-
616- // go over all possible positions of the 3 vertices relative to the plane
617- switch (splitType (side[0 ], side[1 ], side[2 ]))
618- {
619- // all point on one side of the plane (or on the plane)
620- // in this case we simply add the complete triangle
621- // to the proper halve of the subtree
622- case splitType (-1 , -1 , -1 ):
623- case splitType (-1 , -1 , 0 ):
624- case splitType (-1 , 0 , -1 ):
625- case splitType (-1 , 0 , 0 ):
626- case splitType ( 0 , -1 , -1 ):
627- case splitType ( 0 , -1 , 0 ):
628- case splitType ( 0 , 0 , -1 ):
629- complete = classifyTriangle (n->behind .get (), v1, v2, v3, inside, keepEdge, out, inside);
630- clipped = false ;
631- break ;
632-
633- default :
634- case splitType ( 0 , 0 , 1 ):
635- case splitType ( 0 , 1 , 0 ):
636- case splitType ( 0 , 1 , 1 ):
637- case splitType ( 1 , 0 , 0 ):
638- case splitType ( 1 , 0 , 1 ):
639- case splitType ( 1 , 1 , 0 ):
640- case splitType ( 1 , 1 , 1 ):
641- complete = classifyTriangle (n->infront .get (), v1, v2, v3, inside, keepEdge, out, !inside);
642- clipped = false ;
643- break ;
644-
645- // triangle on the dividing plane
646- case splitType ( 0 , 0 , 0 ):
647- if (keepEdge)
648- {
649- append (out, v1, v2, v3);
650- clipped = false ;
651- }
652- break ;
653-
654- // and now all the ways that the triangle can be cut by the plane
655- case splitType ( 1 , -1 , 0 ):
656- complete &= classifyTriangle (n->behind .get (), v2, v3, tmp[A[0 ]], inside, keepEdge, out, inside);
657- complete &= classifyTriangle (n->infront .get (), v3, v1, tmp[A[0 ]], inside, keepEdge, out, !inside);
658- break ;
659-
660- case splitType (-1 , 0 , 1 ):
661- complete &= classifyTriangle (n->behind .get (), v1, v2, tmp[A[2 ]], inside, keepEdge, out, inside);
662- complete &= classifyTriangle (n->infront .get (), v2, v3, tmp[A[2 ]], inside, keepEdge, out, !inside);
663- break ;
664-
665- case splitType ( 0 , 1 , -1 ):
666- complete &= classifyTriangle (n->behind .get (), v3, v1, tmp[A[1 ]], inside, keepEdge, out, inside);
667- complete &= classifyTriangle (n->infront .get (), v1, v2, tmp[A[1 ]], inside, keepEdge, out, !inside);
668- break ;
669-
670- case splitType (-1 , 1 , 0 ):
671- complete &= classifyTriangle (n->behind .get (), v3, v1, tmp[A[0 ]], inside, keepEdge, out, inside);
672- complete &= classifyTriangle (n->infront .get (), v2, v3, tmp[A[0 ]], inside, keepEdge, out, !inside);
673- break ;
674-
675- case splitType ( 1 , 0 , -1 ):
676- complete &= classifyTriangle (n->behind .get (), v2, v3, tmp[A[2 ]], inside, keepEdge, out, inside);
677- complete &= classifyTriangle (n->infront .get (), v1, v2, tmp[A[2 ]], inside, keepEdge, out, !inside);
678- break ;
679-
680- case splitType ( 0 , -1 , 1 ):
681- complete &= classifyTriangle (n->behind .get (), v1, v2, tmp[A[1 ]], inside, keepEdge, out, inside);
682- complete &= classifyTriangle (n->infront .get (), v3, v1, tmp[A[1 ]], inside, keepEdge, out, !inside);
683- break ;
684-
685- case splitType ( 1 , -1 , -1 ):
686- complete &= classifyTriangle (n->infront .get (), v1, tmp[A[0 ]], tmp[A[2 ]], inside, keepEdge, out, !inside);
687- complete &= classifyTriangle (n->behind .get (), v2, tmp[A[2 ]], tmp[A[0 ]], inside, keepEdge, out, inside);
688- complete &= classifyTriangle (n->behind .get (), v2, v3, tmp[A[2 ]], inside, keepEdge, out, inside);
689- break ;
690-
691- case splitType (-1 , 1 , -1 ):
692- complete &= classifyTriangle (n->infront .get (), v2, tmp[A[1 ]], tmp[A[0 ]], inside, keepEdge, out, !inside);
693- complete &= classifyTriangle (n->behind .get (), v3, tmp[A[0 ]], tmp[A[1 ]], inside, keepEdge, out, inside);
694- complete &= classifyTriangle (n->behind .get (), v3, v1, tmp[A[0 ]], inside, keepEdge, out, inside);
695- break ;
696-
697- case splitType (-1 , -1 , 1 ):
698- complete &= classifyTriangle (n->infront .get (), v3, tmp[A[2 ]], tmp[A[1 ]], inside, keepEdge, out, !inside);
699- complete &= classifyTriangle (n->behind .get (), v1, tmp[A[1 ]], tmp[A[2 ]], inside, keepEdge, out, inside);
700- complete &= classifyTriangle (n->behind .get (), v1, v2, tmp[A[1 ]], inside, keepEdge, out, inside);
701- break ;
702-
703- case splitType (-1 , 1 , 1 ):
704- complete &= classifyTriangle (n->behind .get (), v1, tmp[A[0 ]], tmp[A[2 ]], inside, keepEdge, out, inside);
705- complete &= classifyTriangle (n->infront .get (), v2, tmp[A[2 ]], tmp[A[0 ]], inside, keepEdge, out, !inside);
706- complete &= classifyTriangle (n->infront .get (), v2, v3, tmp[A[2 ]], inside, keepEdge, out, !inside);
707- break ;
708-
709- case splitType ( 1 , -1 , 1 ):
710- complete &= classifyTriangle (n->behind .get (), v2, tmp[A[1 ]], tmp[A[0 ]], inside, keepEdge, out, inside);
711- complete &= classifyTriangle (n->infront .get (), v1, tmp[A[0 ]], tmp[A[1 ]], inside, keepEdge, out, !inside);
712- complete &= classifyTriangle (n->infront .get (), v3, v1, tmp[A[1 ]], inside, keepEdge, out, !inside);
713- break ;
714-
715- case splitType ( 1 , 1 , -1 ):
716- complete &= classifyTriangle (n->behind .get (), v3, tmp[A[2 ]], tmp[A[1 ]], inside, keepEdge, out, inside);
717- complete &= classifyTriangle (n->infront .get (), v1, tmp[A[1 ]], tmp[A[2 ]], inside, keepEdge, out, !inside);
718- complete &= classifyTriangle (n->infront .get (), v1, v2, tmp[A[1 ]], inside, keepEdge, out, !inside);
719- break ;
720-
721- default :
722- complete = false ;
723- break ;
724- }
725-
726- if (complete && clipped)
727- {
728- // triangle has been split, but all parts are added to
729- // the output buffer, so remove everything added and add
730- // the whole triangle as a single unit
731- container_traits<C>::resize (out, preAddSize);
732- append (out, v1, v2, v3);
733- }
734-
735- return complete;
736- }
737-
738- // classify the triangles of the tree given as parameter and keep the
739- // polygons that are choosen and put them into out vector
740- // tree: tree to classify
741- // inside: true: keep inside polygons, else keep outside polygons
742- // when inside polygons are kept they are automatically flipped
743- // keepEdge: keep faces that are on the edge of the other polyhedron
744- // out: where to put the triangles
745- void classifyTree (const Node * tree, const C & vertices, bool inside, bool keepEdge, C & out) const
746- {
747- if (tree)
748- {
749- size_type i = 0 ;
750- size_type s = container_traits<I>::getSize (tree->triangles );
751- while (i+2 < s)
752- {
753- auto v1 = getVertIndex (tree->triangles , i );
754- auto v2 = getVertIndex (tree->triangles , i+1 );
755- auto v3 = getVertIndex (tree->triangles , i+2 );
756-
757- classifyTriangle (root_.get (), v1, v2, v3, inside, keepEdge, out, false );
758-
759- i+=3 ;
760- }
761-
762- classifyTree (tree->infront .get (), vertices, inside, keepEdge, out);
763- classifyTree (tree->behind .get (), vertices, inside, keepEdge, out);
764- }
765- }
766-
767527 public:
768528
769529 // / construct the tree, vertices are taken over, indices not
@@ -779,7 +539,6 @@ class BspTree
779539 root_ = makeTree (indices);
780540 }
781541
782-
783542 // / another constructor that assumes that the vertices given are grouped in
784543 // / triples that each represents one triangle
785544 BspTree (C && vertices) : vertices_(std::move(vertices))
@@ -811,69 +570,6 @@ class BspTree
811570 return out;
812571 }
813572
814- // / check if a point is inside the polyhedron defined by the bsp-tree or outside of
815- // / it. This only works, when you defined all your triangles in counter clockwise
816- // / fashion when seen from the outside and also none of the polytopes that you add
817- // / to the tree may intersect
818- // / \param p position you want to check
819- // / \return true, when inside of one of the polytopes
820- bool isInside (const point_type & p) const noexcept
821- {
822- return isInside (p, root_.get ());
823- }
824-
825- // / transform the polygon that this tree describes by the given matrix
826- // / \tparam M matrix type, you have to be able to handle whit matrix
827- // / in the vertex_traits::transform function, otherwise you can use
828- // / whatever you want
829- template <class M >
830- void transform (const M & m) // TODO could be noexcept, if transform is noexcept
831- {
832- // transform all vertices
833- for (auto & v : vertices_)
834- {
835- vertex_traits<vertex_type>::transform (v, m);
836- }
837-
838- // traverse tree and re-calculate all planes
839- reCalculatePlanes (root_.get ());
840- }
841-
842- // / perform boolean operations on the polyhedra defined by the two trees
843- static BspTree<C, I, E> intersect (const BspTree<C, I, E> & lhs, const BspTree<C, I, E> & rhs)
844- {
845- C result;
846-
847- lhs.classifyTree (rhs.root_ .get (), rhs.vertices_ , true , true , result);
848- rhs.classifyTree (lhs.root_ .get (), lhs.vertices_ , true , false , result);
849-
850- return BspTree<C, I, E>(std::move (result));
851- }
852-
853- // / perform boolean operations on the polyhedra defined by the two trees
854- static BspTree<C, I, E> unify (const BspTree<C, I, E> & lhs, const BspTree<C, I, E> & rhs)
855- {
856- C result;
857-
858- lhs.classifyTree (rhs.root_ .get (), rhs.vertices_ , false , true , result);
859- rhs.classifyTree (lhs.root_ .get (), lhs.vertices_ , false , false , result);
860-
861- return BspTree<C, I, E>(std::move (result));
862- }
863-
864- // / perform boolean operations on the polyhedra defined by the two trees
865- static BspTree<C, I, E> subtract (const BspTree<C, I, E> & lhs, const BspTree<C, I, E> & rhs)
866- {
867- C result;
868-
869- lhs.classifyTree (rhs.root_ .get (), rhs.vertices_ , true , true , result);
870- rhs.classifyTree (lhs.root_ .get (), lhs.vertices_ , false , false , result);
871-
872- return BspTree<C, I, E>(std::move (result));
873- }
874-
875573};
876574
877-
878575}
879-
0 commit comments