- BrushSplitByPlaneSelected(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, const char *shader,
- const TextureProjection &projection, EBrushSplit split)
- : m_p0(p0), m_p1(p1), m_p2(p2), m_shader(shader), m_projection(projection), m_split(split)
- {
- }
-
- bool pre(const scene::Path &path, scene::Instance &instance) const
- {
- return true;
- }
-
- void post(const scene::Path &path, scene::Instance &instance) const
- {
- if (path.top().get().visible()) {
- Brush *brush = Node_getBrush(path.top());
- if (brush != 0
- && Instance_getSelectable(instance)->isSelected()) {
- Plane3 plane(plane3_for_points(m_p0, m_p1, m_p2));
- if (plane3_valid(plane)) {
- brushsplit_t split = Brush_classifyPlane(*brush, m_split == eFront ? plane3_flipped(plane) : plane);
- if (split.counts[ePlaneBack] && split.counts[ePlaneFront]) {
- // the plane intersects this brush
- if (m_split == eFrontAndBack) {
- NodeSmartReference node((new BrushNode())->node());
- Brush *fragment = Node_getBrush(node);
- fragment->copy(*brush);
- Face *newFace = fragment->addPlane(m_p0, m_p1, m_p2, m_shader, m_projection);
- if (newFace != 0 && m_split != eFront) {
- newFace->flipWinding();
- }
- fragment->removeEmptyFaces();
- ASSERT_MESSAGE(!fragment->empty(), "brush left with no faces after split");
-
- Node_getTraversable(path.parent())->insert(node);
- {
- scene::Path fragmentPath = path;
- fragmentPath.top() = makeReference(node.get());
- selectPath(fragmentPath, true);
- }
- }
-
- Face *newFace = brush->addPlane(m_p0, m_p1, m_p2, m_shader, m_projection);
- if (newFace != 0 && m_split == eFront) {
- newFace->flipWinding();
- }
- brush->removeEmptyFaces();
- ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after split");
- } else
- // the plane does not intersect this brush
- if (m_split != eFrontAndBack && split.counts[ePlaneBack] != 0) {
- // the brush is "behind" the plane
- Path_deleteTop(path);
- }
- }
- }
- }
- }
+BrushSplitByPlaneSelected( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection, EBrushSplit split )
+ : m_p0( p0 ), m_p1( p1 ), m_p2( p2 ), m_shader( shader ), m_projection( projection ), m_split( split ){
+}
+
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ return true;
+}
+
+void post( const scene::Path& path, scene::Instance& instance ) const {
+ if ( !path.top().get().visible() ) {
+ return;
+ }
+
+ Brush* brush = Node_getBrush( path.top() );
+ if ( brush == nullptr || !Instance_getSelectable( instance )->isSelected() ) {
+ return;
+ }
+
+ Plane3 plane( plane3_for_points( m_p0, m_p1, m_p2 ) );
+ if ( !plane3_valid( plane ) ) {
+ return;
+ }
+
+ brushsplit_t split = Brush_classifyPlane( *brush, m_split == eFront ? plane3_flipped( plane ) : plane );
+ if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
+ // the plane intersects this brush
+ if ( m_split == eFrontAndBack ) {
+ NodeSmartReference node( ( new BrushNode() )->node() );
+ Brush* fragment = Node_getBrush( node );
+ fragment->copy( *brush );
+ std::shared_ptr<Face> newFace =
+ fragment->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
+ if ( newFace != 0 && m_split != eFront ) {
+ newFace->flipWinding();
+ }
+ fragment->removeEmptyFaces();
+ ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" );
+
+ Node_getTraversable( path.parent() )->insert( node );
+ {
+ scene::Path fragmentPath = path;
+ fragmentPath.top() = makeReference( node.get() );
+ selectPath( fragmentPath, true );
+ }
+ }
+
+ std::shared_ptr<Face> newFace = brush->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
+ if ( newFace != 0 && m_split == eFront ) {
+ newFace->flipWinding();
+ }
+ brush->removeEmptyFaces();
+ ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" );
+ }
+ else
+ // the plane does not intersect this brush
+ if ( m_split != eFrontAndBack && split.counts[ePlaneBack] != 0 ) {
+ // the brush is "behind" the plane
+ Path_deleteTop( path );
+ }
+}