+
+ //const int bfrom = quad->side[0].from;
+ //const int rfrom = quad->side[1].from;
+ const int tfrom = quad->side[2].from;
+ //const int lfrom = quad->side[3].from;
+ {
+ const vector<UVPtStruct>& uv_eb_vec = quad->side[0].GetUVPtStruct(true,0);
+ const vector<UVPtStruct>& uv_er_vec = quad->side[1].GetUVPtStruct(false,1);
+ const vector<UVPtStruct>& uv_et_vec = quad->side[2].GetUVPtStruct(true,1);
+ const vector<UVPtStruct>& uv_el_vec = quad->side[3].GetUVPtStruct(false,0);
+ if (uv_eb_vec.empty() ||
+ uv_er_vec.empty() ||
+ uv_et_vec.empty() ||
+ uv_el_vec.empty())
+ return error(COMPERR_BAD_INPUT_MESH);
+ }
+ FaceQuadStruct::SideIterator uv_eb, uv_er, uv_et, uv_el;
+ uv_eb.Init( quad->side[0] );
+ uv_er.Init( quad->side[1] );
+ uv_et.Init( quad->side[2] );
+ uv_el.Init( quad->side[3] );
+
+ gp_UV a0,a1,a2,a3, p0,p1,p2,p3, uv;
+ double x,y;
+
+ a0 = uv_eb[ 0 ].UV();
+ a1 = uv_er[ 0 ].UV();
+ a2 = uv_er[ nr-1 ].UV();
+ a3 = uv_et[ 0 ].UV();
+
+ if ( !myForcedPnts.empty() )
+ {
+ if ( dv != 0 && dh != 0 ) // here myQuadList.size() == 1
+ {
+ const int dmin = Min( dv, dh );
+
+ // Make a side separating domains L and Cb
+ StdMeshers_FaceSidePtr sideLCb;
+ UVPtStruct p3dom; // a point where 3 domains meat
+ { // dmin
+ vector<UVPtStruct> pointsLCb( dmin+1 ); // 1--------1
+ pointsLCb[0] = uv_eb[0]; // | | |
+ for ( int i = 1; i <= dmin; ++i ) // | |Ct|
+ { // | L | |
+ x = uv_et[ i ].normParam; // | |__|
+ y = uv_er[ i ].normParam; // | / |
+ p0 = quad->side[0].grid->Value2d( x ).XY(); // | / Cb |dmin
+ p1 = uv_er[ i ].UV(); // |/ |
+ p2 = uv_et[ i ].UV(); // 0--------0
+ p3 = quad->side[3].grid->Value2d( y ).XY();
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsLCb[ i ].u = uv.X();
+ pointsLCb[ i ].v = uv.Y();
+ }
+ sideLCb = StdMeshers_FaceSide::New( pointsLCb, aFace );
+ p3dom = pointsLCb.back();
+
+ gp_Pnt xyz = S->Value( p3dom.u, p3dom.v );
+ p3dom.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, p3dom.u, p3dom.v );
+ pointsLCb.back() = p3dom;
+ }
+ // Make a side separating domains L and Ct
+ StdMeshers_FaceSidePtr sideLCt;
+ {
+ vector<UVPtStruct> pointsLCt( nl );
+ pointsLCt[0] = p3dom;
+ pointsLCt.back() = uv_et[ dmin ];
+ x = uv_et[ dmin ].normParam;
+ p0 = quad->side[0].grid->Value2d( x ).XY();
+ p2 = uv_et[ dmin ].UV();
+ double y0 = uv_er[ dmin ].normParam;
+ for ( int i = 1; i < nl-1; ++i )
+ {
+ y = y0 + i / ( nl-1. ) * ( 1. - y0 );
+ p1 = quad->side[1].grid->Value2d( y ).XY();
+ p3 = quad->side[3].grid->Value2d( y ).XY();
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsLCt[ i ].u = uv.X();
+ pointsLCt[ i ].v = uv.Y();
+ }
+ sideLCt = StdMeshers_FaceSide::New( pointsLCt, aFace );
+ }
+ // Make a side separating domains Cb and Ct
+ StdMeshers_FaceSidePtr sideCbCt;
+ {
+ vector<UVPtStruct> pointsCbCt( nb );
+ pointsCbCt[0] = p3dom;
+ pointsCbCt.back() = uv_er[ dmin ];
+ y = uv_er[ dmin ].normParam;
+ p1 = uv_er[ dmin ].UV();
+ p3 = quad->side[3].grid->Value2d( y ).XY();
+ double x0 = uv_et[ dmin ].normParam;
+ for ( int i = 1; i < nb-1; ++i )
+ {
+ x = x0 + i / ( nb-1. ) * ( 1. - x0 );
+ p2 = quad->side[2].grid->Value2d( x ).XY();
+ p0 = quad->side[0].grid->Value2d( x ).XY();
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsCbCt[ i ].u = uv.X();
+ pointsCbCt[ i ].v = uv.Y();
+ }
+ sideCbCt = StdMeshers_FaceSide::New( pointsCbCt, aFace );
+ }
+ // Make Cb quad
+ FaceQuadStruct* qCb = new FaceQuadStruct( quad->face, "Cb" );
+ myQuadList.push_back( FaceQuadStruct::Ptr( qCb ));
+ qCb->side.resize(4);
+ qCb->side[0] = quad->side[0];
+ qCb->side[1] = quad->side[1];
+ qCb->side[2] = sideCbCt;
+ qCb->side[3] = sideLCb;
+ qCb->side[1].to = dmin+1;
+ // Make L quad
+ FaceQuadStruct* qL = new FaceQuadStruct( quad->face, "L" );
+ myQuadList.push_back( FaceQuadStruct::Ptr( qL ));
+ qL->side.resize(4);
+ qL->side[0] = sideLCb;
+ qL->side[1] = sideLCt;
+ qL->side[2] = quad->side[2];
+ qL->side[3] = quad->side[3];
+ qL->side[2].to = dmin+1;
+ // Make Ct from the main quad
+ FaceQuadStruct::Ptr qCt = quad;
+ qCt->side[0] = sideCbCt;
+ qCt->side[3] = sideLCt;
+ qCt->side[1].from = dmin;
+ qCt->side[2].from = dmin;
+ qCt->uv_grid.clear();
+ qCt->name = "Ct";
+
+ // Connect sides
+ qCb->side[3].AddContact( dmin, & qCb->side[2], 0 );
+ qCb->side[3].AddContact( dmin, & qCt->side[3], 0 );
+ qCt->side[3].AddContact( 0, & qCt->side[0], 0 );
+ qCt->side[0].AddContact( 0, & qL ->side[0], dmin );
+ qL ->side[0].AddContact( dmin, & qL ->side[1], 0 );
+ qL ->side[0].AddContact( dmin, & qCb->side[2], 0 );
+
+ if ( dh == dv )
+ return computeQuadDominant( aMesh, aFace );
+ else
+ return computeQuadPref( aMesh, aFace, qCt );
+
+ } // if ( dv != 0 && dh != 0 )
+
+ //const int db = quad->side[0].IsReversed() ? -1 : +1;
+ //const int dr = quad->side[1].IsReversed() ? -1 : +1;
+ const int dt = quad->side[2].IsReversed() ? -1 : +1;
+ //const int dl = quad->side[3].IsReversed() ? -1 : +1;
+
+ // Case dv == 0, here possibly myQuadList.size() > 1
+ //
+ // lw nb lw = dh/2
+ // +------------+
+ // | | | |
+ // | | Ct | |
+ // | L | | R |
+ // | |____| |
+ // | / \ |
+ // | / Cb \ |
+ // |/ \|
+ // +------------+
+ const int lw = dh/2; // lateral width
+
+ double yCbL, yCbR;
+ {
+ double lL = quad->side[3].Length();
+ double lLwL = quad->side[2].Length( tfrom,
+ tfrom + ( lw ) * dt );
+ yCbL = lLwL / ( lLwL + lL );
+
+ double lR = quad->side[1].Length();
+ double lLwR = quad->side[2].Length( tfrom + ( lw + nb-1 ) * dt,
+ tfrom + ( lw + nb-1 + lw ) * dt);
+ yCbR = lLwR / ( lLwR + lR );
+ }
+ // Make sides separating domains Cb and L and R
+ StdMeshers_FaceSidePtr sideLCb, sideRCb;
+ UVPtStruct pTBL, pTBR; // points where 3 domains meat
+ {
+ vector<UVPtStruct> pointsLCb( lw+1 ), pointsRCb( lw+1 );
+ pointsLCb[0] = uv_eb[ 0 ];
+ pointsRCb[0] = uv_eb[ nb-1 ];
+ for ( int i = 1, i2 = nt-2; i <= lw; ++i, --i2 )
+ {
+ x = quad->side[2].Param( i );
+ y = yCbL * i / lw;
+ p0 = quad->side[0].Value2d( x );
+ p1 = quad->side[1].Value2d( y );
+ p2 = uv_et[ i ].UV();
+ p3 = quad->side[3].Value2d( y );
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsLCb[ i ].u = uv.X();
+ pointsLCb[ i ].v = uv.Y();
+ pointsLCb[ i ].x = x;
+
+ x = quad->side[2].Param( i2 );
+ y = yCbR * i / lw;
+ p1 = quad->side[1].Value2d( y );
+ p0 = quad->side[0].Value2d( x );
+ p2 = uv_et[ i2 ].UV();
+ p3 = quad->side[3].Value2d( y );
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsRCb[ i ].u = uv.X();
+ pointsRCb[ i ].v = uv.Y();
+ pointsRCb[ i ].x = x;
+ }
+ sideLCb = StdMeshers_FaceSide::New( pointsLCb, aFace );
+ sideRCb = StdMeshers_FaceSide::New( pointsRCb, aFace );
+ pTBL = pointsLCb.back();
+ pTBR = pointsRCb.back();
+ {
+ gp_Pnt xyz = S->Value( pTBL.u, pTBL.v );
+ pTBL.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, pTBL.u, pTBL.v );
+ pointsLCb.back() = pTBL;
+ }
+ {
+ gp_Pnt xyz = S->Value( pTBR.u, pTBR.v );
+ pTBR.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, pTBR.u, pTBR.v );
+ pointsRCb.back() = pTBR;
+ }
+ }
+ // Make sides separating domains Ct and L and R
+ StdMeshers_FaceSidePtr sideLCt, sideRCt;
+ {
+ vector<UVPtStruct> pointsLCt( nl ), pointsRCt( nl );
+ pointsLCt[0] = pTBL;
+ pointsLCt.back() = uv_et[ lw ];
+ pointsRCt[0] = pTBR;
+ pointsRCt.back() = uv_et[ lw + nb - 1 ];
+ x = pTBL.x;
+ p0 = quad->side[0].Value2d( x );
+ p2 = uv_et[ lw ].UV();
+ int iR = lw + nb - 1;
+ double xR = pTBR.x;
+ gp_UV p0R = quad->side[0].Value2d( xR );
+ gp_UV p2R = uv_et[ iR ].UV();
+ for ( int i = 1; i < nl-1; ++i )
+ {
+ y = yCbL + ( 1. - yCbL ) * i / (nl-1.);
+ p1 = quad->side[1].Value2d( y );
+ p3 = quad->side[3].Value2d( y );
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsLCt[ i ].u = uv.X();
+ pointsLCt[ i ].v = uv.Y();
+
+ y = yCbR + ( 1. - yCbR ) * i / (nl-1.);
+ p1 = quad->side[1].Value2d( y );
+ p3 = quad->side[3].Value2d( y );
+ uv = calcUV( xR,y, a0,a1,a2,a3, p0R,p1,p2R,p3 );
+ pointsRCt[ i ].u = uv.X();
+ pointsRCt[ i ].v = uv.Y();
+ }
+ sideLCt = StdMeshers_FaceSide::New( pointsLCt, aFace );
+ sideRCt = StdMeshers_FaceSide::New( pointsRCt, aFace );
+ }
+ // Make a side separating domains Cb and Ct
+ StdMeshers_FaceSidePtr sideCbCt;
+ {
+ vector<UVPtStruct> pointsCbCt( nb );
+ pointsCbCt[0] = pTBL;
+ pointsCbCt.back() = pTBR;
+ p1 = quad->side[1].Value2d( yCbR );
+ p3 = quad->side[3].Value2d( yCbL );
+ for ( int i = 1; i < nb-1; ++i )
+ {
+ x = quad->side[2].Param( i + lw );
+ y = yCbL + ( yCbR - yCbL ) * i / (nb-1.);
+ p2 = uv_et[ i + lw ].UV();
+ p0 = quad->side[0].Value2d( x );
+ uv = calcUV( x,y, a0,a1,a2,a3, p0,p1,p2,p3 );
+ pointsCbCt[ i ].u = uv.X();
+ pointsCbCt[ i ].v = uv.Y();
+ }
+ sideCbCt = StdMeshers_FaceSide::New( pointsCbCt, aFace );
+ }
+ // Make Cb quad
+ FaceQuadStruct* qCb = new FaceQuadStruct( quad->face, "Cb" );
+ myQuadList.push_back( FaceQuadStruct::Ptr( qCb ));
+ qCb->side.resize(4);
+ qCb->side[0] = quad->side[0];
+ qCb->side[1] = sideRCb;
+ qCb->side[2] = sideCbCt;
+ qCb->side[3] = sideLCb;
+ // Make L quad
+ FaceQuadStruct* qL = new FaceQuadStruct( quad->face, "L" );
+ myQuadList.push_back( FaceQuadStruct::Ptr( qL ));
+ qL->side.resize(4);
+ qL->side[0] = sideLCb;
+ qL->side[1] = sideLCt;
+ qL->side[2] = quad->side[2];
+ qL->side[3] = quad->side[3];
+ qL->side[2].to = ( lw + 1 ) * dt + tfrom;
+ // Make R quad
+ FaceQuadStruct* qR = new FaceQuadStruct( quad->face, "R" );
+ myQuadList.push_back( FaceQuadStruct::Ptr( qR ));
+ qR->side.resize(4);
+ qR->side[0] = sideRCb;
+ qR->side[0].from = lw;
+ qR->side[0].to = -1;
+ qR->side[0].di = -1;
+ qR->side[1] = quad->side[1];
+ qR->side[2] = quad->side[2];
+ qR->side[2].from = ( lw + nb-1 ) * dt + tfrom;
+ qR->side[3] = sideRCt;
+ // Make Ct from the main quad
+ FaceQuadStruct::Ptr qCt = quad;
+ qCt->side[0] = sideCbCt;
+ qCt->side[1] = sideRCt;
+ qCt->side[2].from = ( lw ) * dt + tfrom;
+ qCt->side[2].to = ( lw + nb ) * dt + tfrom;
+ qCt->side[3] = sideLCt;
+ qCt->uv_grid.clear();
+ qCt->name = "Ct";
+
+ // Connect sides
+ qCb->side[3].AddContact( lw, & qCb->side[2], 0 );
+ qCb->side[3].AddContact( lw, & qCt->side[3], 0 );
+ qCt->side[3].AddContact( 0, & qCt->side[0], 0 );
+ qCt->side[0].AddContact( 0, & qL ->side[0], lw );
+ qL ->side[0].AddContact( lw, & qL ->side[1], 0 );
+ qL ->side[0].AddContact( lw, & qCb->side[2], 0 );
+ //
+ qCb->side[1].AddContact( lw, & qCb->side[2], nb-1 );
+ qCb->side[1].AddContact( lw, & qCt->side[1], 0 );
+ qCt->side[0].AddContact( nb-1, & qCt->side[1], 0 );
+ qCt->side[0].AddContact( nb-1, & qR ->side[0], lw );
+ qR ->side[3].AddContact( 0, & qR ->side[0], lw );
+ qR ->side[3].AddContact( 0, & qCb->side[2], nb-1 );
+
+ return computeQuadDominant( aMesh, aFace );
+
+ } // if ( !myForcedPnts.empty() )
+