binds... * clipper::enter, shift+enter, doubleclick: merge brushes and components with clipper points, if no cut occured
This commit is contained in:
parent
07bc303c2d
commit
053df17a35
|
|
@ -33,10 +33,9 @@
|
|||
|
||||
GdkCursor* g_clipper_cursor;
|
||||
|
||||
ClipperPoints g_clipper_points( g_vector3_identity, g_vector3_identity, g_vector3_identity );
|
||||
ClipperPoints g_clipper_points;
|
||||
bool g_clipper_flipped = false;
|
||||
bool g_clipper_quick = false;
|
||||
bool g_clipper_doubleclicked = false;
|
||||
|
||||
/* preferences */
|
||||
bool g_clipper_caulk = true;
|
||||
|
|
@ -55,28 +54,27 @@ void ClipperModeQuick(){
|
|||
}
|
||||
|
||||
|
||||
bool Clipper_ok(){
|
||||
return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && plane3_valid( plane3_for_points( g_clipper_points._points ) );
|
||||
bool Clipper_ok_plane(){
|
||||
return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && g_clipper_points._count > 1 && plane3_valid( plane3_for_points( g_clipper_points._points ) );
|
||||
}
|
||||
|
||||
ClipperPoints Clipper_getPlanePoints(){
|
||||
return g_clipper_flipped? ClipperPoints( g_clipper_points[0], g_clipper_points[2], g_clipper_points[1] ) : g_clipper_points;
|
||||
bool Clipper_ok(){
|
||||
return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && g_clipper_points._count > 0;
|
||||
}
|
||||
|
||||
void Clipper_update(){
|
||||
Scene_BrushSetClipPlane( GlobalSceneGraph(), Clipper_getPlanePoints() );
|
||||
Scene_BrushSetClipPlane( GlobalSceneGraph(), g_clipper_points, g_clipper_flipped );
|
||||
SceneChangeNotify();
|
||||
}
|
||||
|
||||
void Clipper_setPlanePoints( const ClipperPoints& points ){
|
||||
g_clipper_points = points;
|
||||
// g_clipper_doubleclicked = false; //assuming, that new point was set... dragging in fact calls this too >_<
|
||||
Clipper_update();
|
||||
}
|
||||
|
||||
#include "gtkutil/idledraw.h"
|
||||
void Clipper_BoundsChanged(){
|
||||
if ( Clipper_ok() )
|
||||
if ( Clipper_ok_plane() )
|
||||
Clipper_update();
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +116,7 @@ void Clipper_modeChanged( bool isClipper ){
|
|||
|
||||
|
||||
void Clipper_do( bool split ){
|
||||
Scene_BrushSplitByPlane( GlobalSceneGraph(), Clipper_getPlanePoints(), g_clipper_caulk, split );
|
||||
Scene_BrushSplitByPlane( GlobalSceneGraph(), g_clipper_points, g_clipper_flipped, g_clipper_caulk, split );
|
||||
if( g_clipper_resetPoints ){
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eClip ); /* reset points this way */
|
||||
if( g_clipper_resetFlip )
|
||||
|
|
@ -144,7 +142,7 @@ void Clipper_doSplit(){
|
|||
}
|
||||
|
||||
void Clipper_doFlip(){
|
||||
if( Clipper_ok() ){
|
||||
if( Clipper_ok_plane() ){
|
||||
g_clipper_flipped = !g_clipper_flipped;
|
||||
Clipper_update();
|
||||
}
|
||||
|
|
@ -152,13 +150,17 @@ void Clipper_doFlip(){
|
|||
|
||||
#include "timer.h"
|
||||
Timer g_clipper_timer;
|
||||
void Clipper_tryDoubleclick(){
|
||||
g_clipper_doubleclicked = g_clipper_timer.elapsed_msec() < 200 && Clipper_ok();
|
||||
bool g_clipper_doubleclicked = false;
|
||||
std::size_t g_clipper_doubleclicked_point = 0; //monitor clicking the same point twice
|
||||
|
||||
void Clipper_tryDoubleclick(){ //onMouseDown
|
||||
g_clipper_doubleclicked = g_clipper_timer.elapsed_msec() < 200;
|
||||
g_clipper_timer.start();
|
||||
g_clipper_doubleclicked_point = g_clipper_points._count;
|
||||
}
|
||||
|
||||
void Clipper_tryDoubleclickedCut(){
|
||||
if( g_clipper_doubleclicked ){
|
||||
void Clipper_tryDoubleclickedCut(){ //onMouseUp
|
||||
if( g_clipper_doubleclicked && g_clipper_doubleclicked_point == g_clipper_points._count ){
|
||||
g_clipper_doubleclicked = false;
|
||||
return g_clipper_doubleclicked_split? Clipper_doSplit() : Clipper_doClip();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,15 @@ class ClipperPoints
|
|||
{
|
||||
public:
|
||||
Vector3 _points[3];
|
||||
ClipperPoints( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
|
||||
std::size_t _count;
|
||||
ClipperPoints( const Vector3& p0, const Vector3& p1, const Vector3& p2, std::size_t count ){
|
||||
_points[0] = p0;
|
||||
_points[1] = p1;
|
||||
_points[2] = p2;
|
||||
_count = count;
|
||||
}
|
||||
ClipperPoints() : _count( 0 ){
|
||||
_points[0] = _points[1] = _points[2] = Vector3( 0, 0, 0 );
|
||||
}
|
||||
const Vector3& operator[]( std::size_t i ) const {
|
||||
return _points[i];
|
||||
|
|
|
|||
|
|
@ -744,14 +744,17 @@ void CSG_Subtract(){
|
|||
#include "clippertool.h"
|
||||
class BrushSplitByPlaneSelected : public scene::Graph::Walker
|
||||
{
|
||||
const Plane3 m_plane;
|
||||
const ClipperPoints m_points;
|
||||
const Plane3 m_plane;
|
||||
const char* m_shader;
|
||||
const TextureProjection& m_projection;
|
||||
const bool m_split; /* split or clip */
|
||||
public:
|
||||
BrushSplitByPlaneSelected( const ClipperPoints& points, const char* shader, const TextureProjection& projection, bool split )
|
||||
: m_plane( plane3_for_points( points._points ) ), m_points( points ), m_shader( shader ), m_projection( projection ), m_split( split ){
|
||||
mutable bool m_gj;
|
||||
BrushSplitByPlaneSelected( const ClipperPoints& points, bool flip, const char* shader, const TextureProjection& projection, bool split )
|
||||
: m_points( flip? ClipperPoints( points[0], points[2], points[1], points._count ) : points ),
|
||||
m_plane( plane3_for_points( m_points[0], m_points[1], m_points[2] ) ),
|
||||
m_shader( shader ), m_projection( projection ), m_split( split ), m_gj( false ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
return true;
|
||||
|
|
@ -764,11 +767,12 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
|
|||
const brushsplit_t split = Brush_classifyPlane( *brush, m_plane );
|
||||
if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
|
||||
// the plane intersects this brush
|
||||
m_gj = true;
|
||||
if ( m_split ) {
|
||||
NodeSmartReference node( ( new BrushNode() )->node() );
|
||||
Brush* fragment = Node_getBrush( node );
|
||||
fragment->copy( *brush );
|
||||
fragment->addPlane( m_points[0], m_points[2], m_points[1], m_shader, m_projection ); /* flip plane points */
|
||||
fragment->addPlane( m_points[0], m_points[1], m_points[2], m_shader, m_projection );
|
||||
fragment->removeEmptyFaces();
|
||||
ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" );
|
||||
|
||||
|
|
@ -780,7 +784,7 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
}
|
||||
|
||||
brush->addPlane( m_points[0], m_points[1], m_points[2], m_shader, m_projection );
|
||||
brush->addPlane( m_points[0], m_points[2], m_points[1], m_shader, m_projection );
|
||||
brush->removeEmptyFaces();
|
||||
ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" );
|
||||
}
|
||||
|
|
@ -788,6 +792,7 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
|
|||
// the plane does not intersect this brush
|
||||
if ( !m_split && split.counts[ePlaneFront] != 0 ) {
|
||||
// the brush is "behind" the plane
|
||||
m_gj = true;
|
||||
Path_deleteTop( path );
|
||||
}
|
||||
}
|
||||
|
|
@ -795,12 +800,18 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
};
|
||||
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const ClipperPoints& points, bool caulk, bool split ){
|
||||
void CSG_WrapMerge( const ClipperPoints& clipperPoints );
|
||||
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const ClipperPoints& points, bool flip, bool caulk, bool split ){
|
||||
const char* shader = caulk? GetCaulkShader() : TextureBrowser_GetSelectedShader();
|
||||
TextureProjection projection;
|
||||
TexDef_Construct_Default( projection );
|
||||
graph.traverse( BrushSplitByPlaneSelected( points, shader, projection, split ) );
|
||||
SceneChangeNotify();
|
||||
BrushSplitByPlaneSelected dosplit( points, flip, shader, projection, split );
|
||||
if( points._count > 1 && plane3_valid( plane3_for_points( points._points ) ) )
|
||||
graph.traverse( dosplit );
|
||||
if( !dosplit.m_gj ){
|
||||
CSG_WrapMerge( points );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -808,8 +819,8 @@ class BrushInstanceSetClipPlane : public scene::Graph::Walker
|
|||
{
|
||||
const Plane3 m_plane;
|
||||
public:
|
||||
BrushInstanceSetClipPlane( const ClipperPoints& points )
|
||||
: m_plane( plane3_for_points( points._points ) ){
|
||||
BrushInstanceSetClipPlane( const ClipperPoints& points, bool flip )
|
||||
: m_plane( points._count < 2? Plane3( 0, 0, 0, 0 ) : flip? plane3_for_points( points[0], points[2], points[1] ) : plane3_for_points( points[0], points[1], points[2] ) ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
BrushInstance* brush = Instance_getBrush( instance );
|
||||
|
|
@ -823,8 +834,8 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
};
|
||||
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const ClipperPoints& points ){
|
||||
graph.traverse( BrushInstanceSetClipPlane( points ) );
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const ClipperPoints& points, bool flip ){
|
||||
graph.traverse( BrushInstanceSetClipPlane( points, flip ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -970,7 +981,6 @@ void CSG_Merge( void ){
|
|||
selectPath( path, true );
|
||||
|
||||
globalOutputStream() << "CSG Merge: Succeeded.\n";
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1073,7 +1083,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void CSG_WrapMerge(){
|
||||
void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
|
||||
const bool primit = ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive );
|
||||
brush_vector_t selected_brushes;
|
||||
if( primit )
|
||||
|
|
@ -1096,6 +1106,9 @@ void CSG_WrapMerge(){
|
|||
|
||||
GlobalSceneGraph().traverse( Scene_gatherSelectedComponents( mergeVertices ) );
|
||||
|
||||
for( std::size_t i = 0; i < clipperPoints._count; ++i )
|
||||
mergeVertices.insert( clipperPoints[i] );
|
||||
|
||||
//globalOutputStream() << mergeVertices.size() << " mergeVertices.size()\n";
|
||||
if( mergeVertices.size() < 4 ){
|
||||
globalWarningStream() << "CSG Wrap Merge: Too few vertices: " << mergeVertices.size() << ".\n";
|
||||
|
|
@ -1135,8 +1148,6 @@ void CSG_WrapMerge(){
|
|||
return;
|
||||
}
|
||||
|
||||
UndoableCommand undo( "brushWrapMerge" );
|
||||
|
||||
NodeSmartReference node( ( new BrushNode() )->node() );
|
||||
Brush* brush = Node_getBrush( node );
|
||||
|
||||
|
|
@ -1173,6 +1184,11 @@ void CSG_WrapMerge(){
|
|||
}
|
||||
}
|
||||
|
||||
void CSG_WrapMerge(){
|
||||
UndoableCommand undo( "brushWrapMerge" );
|
||||
CSG_WrapMerge( ClipperPoints() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
class find_instance_to_DeleteComponents : public SelectionSystem::Visitor
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class Graph;
|
|||
|
||||
class ClipperPoints;
|
||||
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const ClipperPoints& points );
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const ClipperPoints& points, bool caulk, bool split );
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const ClipperPoints& points, bool flip );
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const ClipperPoints& points, bool flip, bool caulk, bool split );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4047,19 +4047,34 @@ public:
|
|||
}
|
||||
}
|
||||
void updatePlane(){
|
||||
if( m_points[0].m_set && m_points[1].m_set ){
|
||||
if( !m_points[2].m_set ){
|
||||
std::size_t npoints = 0;
|
||||
for(; npoints < 3; )
|
||||
if( m_points[npoints].m_set )
|
||||
++npoints;
|
||||
else
|
||||
break;
|
||||
|
||||
switch ( npoints )
|
||||
{
|
||||
case 1:
|
||||
Clipper_setPlanePoints( ClipperPoints( m_points[0].m_point, m_points[0].m_point, m_points[0].m_point, npoints ) );
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
if( m_view->fill() ){ //3d
|
||||
viewdir_fixup();
|
||||
m_points[2].m_point = m_points[0].m_point + m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point );
|
||||
viewdir_make_cut_worthy( plane3_for_points( m_points[0].m_point, m_points[2].m_point, m_points[1].m_point ) );
|
||||
viewdir_make_cut_worthy( plane3_for_points( m_points[0].m_point, m_points[1].m_point, m_points[2].m_point ) );
|
||||
}
|
||||
m_points[2].m_point = m_points[0].m_point + m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point );
|
||||
}
|
||||
Clipper_setPlanePoints( ClipperPoints( m_points[0].m_point, m_points[2].m_point, m_points[1].m_point ) ); /* points order corresponds the plane, we want to insert */
|
||||
}
|
||||
else{
|
||||
Clipper_setPlanePoints( ClipperPoints( g_vector3_identity, g_vector3_identity, g_vector3_identity ) );
|
||||
case 3:
|
||||
Clipper_setPlanePoints( ClipperPoints( m_points[0].m_point, m_points[1].m_point, m_points[2].m_point, npoints ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
Clipper_setPlanePoints( ClipperPoints() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::size_t newPointIndex( bool viewfill ) const {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user