* DragExtrudeFaces: diagonal extruded brushes joints if extruding multiple faces per brush
This commit is contained in:
parent
d664d15f17
commit
6e88e7b746
|
|
@ -216,7 +216,7 @@ public:
|
|||
}
|
||||
}
|
||||
};
|
||||
/* brush0, brush2 are supposed to have same amount of faces in the same order */
|
||||
/* brush0, brush2 are supposed to have same amount of faces in the same order; brush2 bigger than brush0 */
|
||||
void brush_extrudeDiag( const Brush& brush0, const Brush& brush2, brush_vector_t& m_out, const HollowSettings& m_settings ){
|
||||
TextureProjection projection;
|
||||
TexDef_Construct_Default( projection );
|
||||
|
|
|
|||
|
|
@ -811,6 +811,15 @@ public:
|
|||
BrushInstance* m_brushInstance;
|
||||
struct InFaceOutBrush{ Face* m_face; PlanePoints m_planepoints; Brush* m_outBrush; };
|
||||
std::vector<InFaceOutBrush> m_faces;
|
||||
std::vector<InFaceOutBrush>::iterator faceFind( const Face* face ){
|
||||
return std::find_if( m_faces.begin(), m_faces.end(), [face]( const InFaceOutBrush& infaceoutbrush ){ return face == infaceoutbrush.m_face; } );
|
||||
}
|
||||
std::vector<InFaceOutBrush>::const_iterator faceFind( const Face* face ) const {
|
||||
return std::find_if( m_faces.begin(), m_faces.end(), [face]( const InFaceOutBrush& infaceoutbrush ){ return face == infaceoutbrush.m_face; } );
|
||||
}
|
||||
bool faceExcluded( const Face* face ) const {
|
||||
return faceFind( face ) == m_faces.end();
|
||||
}
|
||||
};
|
||||
std::vector<ExtrudeSource> m_extrudeSources;
|
||||
|
||||
|
|
@ -891,6 +900,14 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
}
|
||||
}
|
||||
for( ExtrudeSource& source : m_extrudeSources ){
|
||||
Brush& brush0 = source.m_brushInstance->getBrush();
|
||||
if( source.m_faces.size() > 1 ){
|
||||
Brush* tmpbrush = new Brush( brush0 );
|
||||
offsetFaces( source, *tmpbrush, offset );
|
||||
brush_extrudeDiag( brush0, *tmpbrush, source );
|
||||
delete tmpbrush;
|
||||
}
|
||||
else{
|
||||
for( auto& infaceoutbrush : source.m_faces ){
|
||||
const Face* face = infaceoutbrush.m_face;
|
||||
Brush* brush = infaceoutbrush.m_outBrush;
|
||||
|
|
@ -906,9 +923,10 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
|
||||
for( const WindingVertex& vertex : face->getWinding() ){
|
||||
if( vertex.adjacent != c_brush_maxFaces ){
|
||||
Brush::const_iterator faceIt = source.m_brushInstance->getBrush().begin();
|
||||
Brush::const_iterator faceIt = brush0.begin();
|
||||
std::advance( faceIt, vertex.adjacent );
|
||||
f = brush->addFace( **faceIt );
|
||||
brush->addFace( **faceIt );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -931,6 +949,15 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
face->getPlane().copy( infaceoutbrush.m_planepoints );
|
||||
face->planeChanged();
|
||||
}
|
||||
if( source.m_faces.size() > 1 ){
|
||||
Brush* tmpbrush = new Brush( brush0 );
|
||||
tmpbrush->evaluateBRep();
|
||||
offsetFaces( source, brush0, offset );
|
||||
if( brush0.hasContributingFaces() )
|
||||
brush_extrudeDiag( brush0, *tmpbrush, source );
|
||||
delete tmpbrush;
|
||||
}
|
||||
else{
|
||||
for( auto& infaceoutbrush : source.m_faces ){
|
||||
Face* face = infaceoutbrush.m_face;
|
||||
Brush* brush = infaceoutbrush.m_outBrush;
|
||||
|
|
@ -939,24 +966,133 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
brush->copy( brush0 );
|
||||
|
||||
Face* f = brush->addFace( *face );
|
||||
face->assign_planepts( infaceoutbrush.m_planepoints );
|
||||
f->getPlane().offset( offset );
|
||||
f->getPlane().reverse();
|
||||
f->planeChanged();
|
||||
|
||||
brush->removeEmptyFaces();
|
||||
// modify original brush
|
||||
face->getPlane().copy( infaceoutbrush.m_planepoints );
|
||||
face->getPlane().offset( offset );
|
||||
face->planeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void set0( const Vector3& start, const Plane3& planeSelected ){
|
||||
m_0 = start;
|
||||
m_planeSelected = planeSelected;
|
||||
}
|
||||
|
||||
private:
|
||||
void offsetFaces( const ExtrudeSource& source, Brush& brush, const float offset ){
|
||||
const Brush& brush0 = source.m_brushInstance->getBrush();
|
||||
for( Brush::const_iterator i0 = brush0.begin(); i0 != brush0.end(); ++i0 ){
|
||||
const Face& face0 = *( *i0 );
|
||||
if( !source.faceExcluded( &face0 ) ){
|
||||
Brush::const_iterator i = brush.begin();
|
||||
std::advance( i, std::distance( brush0.begin(), i0 ) );
|
||||
Face& face = *( *i );
|
||||
face.getPlane().offset( offset );
|
||||
face.planeChanged();
|
||||
}
|
||||
}
|
||||
brush.evaluateBRep();
|
||||
}
|
||||
/* brush0, brush2 are supposed to have same amount of faces in the same order; brush2 bigger than brush0 */
|
||||
void brush_extrudeDiag( const Brush& brush0, const Brush& brush2, ExtrudeSource& source ){
|
||||
TextureProjection projection;
|
||||
TexDef_Construct_Default( projection );
|
||||
|
||||
for( Brush::const_iterator i0 = brush0.begin(); i0 != brush0.end(); ++i0 ){
|
||||
const Face& face0 = *( *i0 );
|
||||
Brush::const_iterator i2 = brush2.begin();
|
||||
std::advance( i2, std::distance( brush0.begin(), i0 ) );
|
||||
const Face& face2 = *( *i2 );
|
||||
|
||||
auto infaceoutbrush_iter = source.faceFind( &face0 ); // brush0 = source.m_brushInstance->getBrush()
|
||||
if( infaceoutbrush_iter != source.m_faces.end() ) {
|
||||
if( face0.contributes() || face2.contributes() ) {
|
||||
const char* shader = face0.GetShader();
|
||||
|
||||
Brush* outBrush = ( *infaceoutbrush_iter ).m_outBrush;
|
||||
outBrush->clear();
|
||||
|
||||
if( face0.contributes() ){
|
||||
if( Face* newFace = outBrush->addFace( face0 ) ) {
|
||||
newFace->flipWinding();
|
||||
}
|
||||
}
|
||||
if( face2.contributes() ){
|
||||
outBrush->addFace( face2 );
|
||||
}
|
||||
|
||||
if( face0.contributes() && face2.contributes() ){ //sew two valid windings
|
||||
const auto addSidePlanes = [&outBrush, shader, &projection]( const Winding& winding0, const Winding& winding2, const DoubleVector3 normal, const bool swap ){
|
||||
for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){
|
||||
const std::size_t next = Winding_next( winding0, index0 );
|
||||
Vector3 BestPoint;
|
||||
double bestdot = -1;
|
||||
for( std::size_t index2 = 0; index2 < winding2.numpoints; ++index2 ){
|
||||
const double dot = vector3_dot(
|
||||
vector3_normalised(
|
||||
vector3_cross(
|
||||
winding0[index0].vertex - winding0[next].vertex,
|
||||
winding0[index0].vertex - winding2[index2].vertex
|
||||
)
|
||||
),
|
||||
normal
|
||||
);
|
||||
if( dot > bestdot ) {
|
||||
bestdot = dot;
|
||||
BestPoint = winding2[index2].vertex;
|
||||
}
|
||||
}
|
||||
outBrush->addPlane( winding0[swap? next : index0].vertex,
|
||||
winding0[swap? index0 : next].vertex,
|
||||
BestPoint,
|
||||
shader,
|
||||
projection );
|
||||
}
|
||||
};
|
||||
//insert side planes from each winding perspective, as their form may change after brush expansion
|
||||
addSidePlanes( face0.getWinding(), face2.getWinding(), face0.getPlane().plane3().normal(), false );
|
||||
addSidePlanes( face2.getWinding(), face0.getWinding(), face0.getPlane().plane3().normal(), true );
|
||||
}
|
||||
else{ //one valid winding: this way may produce garbage with complex brushes, extruded partially, but does preferred result with simple ones
|
||||
const auto addSidePlanes = [&outBrush, shader, &projection]( const Winding& winding0, const Brush& brush2, const Plane3 plane, const bool swap ){
|
||||
for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){
|
||||
const std::size_t next = Winding_next( winding0, index0 );
|
||||
Vector3 BestPoint;
|
||||
double bestdist = 999999;
|
||||
for( const Face* f : brush2 ) {
|
||||
const Winding& winding2 = f->getWinding();
|
||||
for( std::size_t index2 = 0; index2 < winding2.numpoints; ++index2 ){
|
||||
const double testdist = vector3_length( winding0[index0].vertex - winding2[index2].vertex );
|
||||
if( testdist < bestdist && plane3_distance_to_point( plane, winding2[index2].vertex ) > .05 ) {
|
||||
bestdist = testdist;
|
||||
BestPoint = winding2[index2].vertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
outBrush->addPlane( winding0[swap? next : index0].vertex,
|
||||
winding0[swap? index0 : next].vertex,
|
||||
BestPoint,
|
||||
shader,
|
||||
projection );
|
||||
}
|
||||
};
|
||||
|
||||
if( face0.contributes() )
|
||||
addSidePlanes( face0.getWinding(), brush2, face0.getPlane().plane3(), false );
|
||||
else if( face2.contributes() )
|
||||
addSidePlanes( face2.getWinding(), brush0, plane3_flipped( face2.getPlane().plane3() ), true );
|
||||
}
|
||||
outBrush->removeEmptyFaces();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user