1 /*---------------------------------------------------------------------------*\
2 * OpenSG NURBS Library *
5 * Copyright (C) 2001-2006 by the University of Bonn, Computer Graphics Group*
7 * http://cg.cs.uni-bonn.de/ *
9 * contact: edhellon@cs.uni-bonn.de, guthe@cs.uni-bonn.de, rk@cs.uni-bonn.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
38 #include "OSGErrorQuadTree.h"
40 #include "OSGDCTPMesh.h"
41 #include "OSGBezierTensorSurface.h"
42 #include "OSGBSplineTensorSurface.h"
52 //#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
53 //#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
55 //#define OSG_EUCLID_ERRORS
60 static char THIS_FILE
[] = __FILE__
;
64 bool CErrorQuadTree::m_sbNormalApproximation
= false;
66 CErrorQuadTree::CErrorQuadTree() :
68 #ifdef OSG_USE_NURBS_PATCH
74 m_fErrorCutoff(DCTP_EPS
)
79 CErrorQuadTree::~CErrorQuadTree()
81 #ifdef OSG_USE_NURBS_PATCH
85 #ifdef OSG_ONE_CHILD_PTR
91 const unsigned int cui_size_u
= m_vvptRoot
.size();
95 const unsigned int cui_size_v
= m_vvptRoot
[0].size();
99 for(ui_u
= 0; ui_u
< cui_size_u
; ++ui_u
)
101 for(ui_v
= 0; ui_v
< cui_size_v
; ++ui_v
)
103 DeleteNode(m_vvptRoot
[ui_u
][ui_v
]);
104 #ifdef OSG_ONE_CHILD_PTR
105 delete m_vvptRoot
[ui_u
][ui_v
];
106 m_vvptRoot
[ui_u
][ui_v
] = NULL
;
116 DeleteBPNode(m_ptBPRoot
);
122 //#ifndef OSG_ARBITRARY_SPLIT
123 void CErrorQuadTree::BuildMesh(DCTPMesh
*pclMesh
,
124 #ifdef OSG_USE_NURBS_PATCH
125 BSplineTensorSurface
*pclPatch
,
126 #ifdef OSG_ARBITRARY_SPLIT
127 const Vec2d cclMinParam
, const Vec2d cclMaxParam
,
130 std::vector
<std::vector
<BezierTensorSurface
> > *pvvclPatches
,
131 const std::vector
<double> *cpvdIntervalsU
,
132 const std::vector
<double> *cpvdIntervalsV
,
134 float fError
, float &rfMinError
, float &rfMaxError
)
137 #ifdef OSG_USE_NURBS_PATCH
138 #ifdef OSG_ARBITRARY_SPLIT
139 SetInitialCells(pclMesh
, fError
, pclPatch
, cclMinParam
, cclMaxParam
);
141 if( (cclMaxParam
[0] - cclMinParam
[0] < DCTP_EPS
) ||
142 (cclMaxParam
[1] - cclMinParam
[1] < DCTP_EPS
) )
147 SetInitialCells(pclMesh
, fError
, pclPatch
);
150 SetInitialCells(pclMesh
, fError
, pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
153 unsigned int ui_face
;
154 unsigned int ui_face_cnt
= UInt32(pclMesh
->faces
.size());
156 SFaceTreeCell
*pt_finfo
;
161 rfMaxError
= FLT_MAX
;
163 if(fError
< m_fErrorCutoff
)
165 fError
= m_fErrorCutoff
;
168 if( (fError
>= m_fMaxError
) && (m_fMaxError
>= 0.0) )
170 // ok, we already have a subdivision for that error...
171 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
173 pcl_face
= pclMesh
->faces
[ui_face
];
174 if(pcl_face
->faceinfo
)
176 f_prev_error
= FLT_MAX
;
177 #ifdef OSG_USE_NURBS_PATCH
178 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
179 while(f_act_error
> fError
)
182 #ifdef OSG_USE_KD_TREE
183 #ifdef OSG_ARBITRARY_SPLIT
184 if( (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fSplitValue
< 0.0)
186 if( (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->bSplitHoriz
)
189 #ifdef OSG_ARBITRARY_SPLIT
190 pclMesh
->SubdivideQuadEW(pcl_face
, -(static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fSplitValue
);
192 pclMesh
->SubdivideQuadEW(pcl_face
);
197 #ifdef OSG_ARBITRARY_SPLIT
198 pclMesh
->SubdivideQuadNS(pcl_face
, (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fSplitValue
);
200 pclMesh
->SubdivideQuadNS(pcl_face
);
203 SubdivideNode(pclMesh
, pcl_face
);
204 ++ui_face_cnt
; // one new face
206 pclMesh
->SubdivideQuad(pcl_face
);
207 SubdivideNode(pclMesh
, pcl_face
);
208 ui_face_cnt
+= 3; // three new faces
210 f_prev_error
= f_act_error
;
211 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
214 if( (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
)
216 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
217 while(f_act_error
> fError
)
219 pclMesh
->SubdivideQuad(pcl_face
);
220 SubdivideNode(pclMesh
, pcl_face
);
221 ui_face_cnt
+= 3; // three new faces
222 f_prev_error
= f_act_error
;
223 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
228 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptBPCell
->fError
;
229 f_prev_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptBPCell
->fPrevError
;
230 // std::cerr << pcl_face->orig_quad[ 3 ]->coords << pcl_face->orig_quad[ 1 ]->coords << std::endl;
231 // std::cerr << f_act_error << ", " << f_prev_error << std::endl;
234 if(f_act_error
> rfMinError
)
236 rfMinError
= f_act_error
;
238 if(f_prev_error
< rfMaxError
)
240 rfMaxError
= f_prev_error
;
246 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
248 pcl_face
= pclMesh
->faces
[ui_face
];
249 pt_finfo
= static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
);
253 pcl_face
->faceinfo
= NULL
;
257 pclMesh->removeFace( ui_face );
263 // std::cerr << "reconstructed " << ui_face_cnt << " faces" << std::endl;
264 /* if( pclMesh->faces.size( ) >= 1000 )
266 if( fError > m_fErrorCutoff )
268 std::cerr << "reduce error cutoff: " << m_fErrorCutoff << " -> " << fError << std::endl;
269 m_fErrorCutoff = fError;
272 if( fError <= m_fErrorCutoff )
279 #ifdef OSG_ARBITRARY_SPLIT
280 #ifndef OSG_USE_NURBS_PATCH
283 // create first surface
284 std::vector
<BSplineTensorSurface
> vcl_surf
;
289 pt_finfo
= (static_cast<SFaceTreeCell
*>(pclMesh
->faces
[0]->faceinfo
) );
290 pt_finfo
->bOwnSurface
= true;
291 pt_finfo
->pclBSplineSurface
= new BSplineTensorSurface
;
292 *(pt_finfo
->pclBSplineSurface
) = *pclPatch
;
293 pclPatch
->getParameterInterval_U(cl_min
[0], cl_add
[0]);
294 pclPatch
->getParameterInterval_V(cl_min
[1], cl_add
[1]);
297 d_split
= (cclMinParam
[0] - cl_min
[0]) / cl_add
[0];
300 if(d_split
> DCTP_EPS
)
302 pt_finfo
->pclBSplineSurface
->subDivisionU(vcl_surf
, d_split
);
303 *(pt_finfo
->pclBSplineSurface
) = vcl_surf
[1];
306 d_split
= (cclMaxParam
[0] - cclMinParam
[0]) / (cl_add
[0] - cclMinParam
[0]);
309 if(1.0 - d_split
> DCTP_EPS
)
311 pt_finfo
->pclBSplineSurface
->subDivisionU(vcl_surf
, d_split
);
312 *(pt_finfo
->pclBSplineSurface
) = vcl_surf
[0];
315 d_split
= (cclMinParam
[1] - cl_min
[1]) / cl_add
[1];
318 if(d_split
> DCTP_EPS
)
320 pt_finfo
->pclBSplineSurface
->subDivisionV(vcl_surf
, d_split
);
321 *(pt_finfo
->pclBSplineSurface
) = vcl_surf
[1];
324 d_split
= (cclMaxParam
[1] - cclMinParam
[1]) / (cl_add
[1] - cclMinParam
[1]);
327 if(1.0 - d_split
> DCTP_EPS
)
329 pt_finfo
->pclBSplineSurface
->subDivisionV(vcl_surf
, d_split
);
330 *(pt_finfo
->pclBSplineSurface
) = vcl_surf
[0];
336 // we need to build a new quadtree
337 /* if( ( fError > m_fMaxError * 0.7071068115 ) && ( m_fMaxError >= 0.0 ) )
339 // new error must be 1 / sqrt( 2 ) or less than old...
340 fError = m_fMaxError * 0.7071068115;
343 // init errors if computed for the first time
344 // if( m_fMaxError < 0.0 )
346 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
348 pcl_face
= pclMesh
->faces
[ui_face
];
349 if(pcl_face
->faceinfo
)
351 if( (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
)
353 ComputeError(pcl_face
);
359 // subdivide and get max error
362 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
364 pcl_face
= pclMesh
->faces
[ui_face
];
365 if(pcl_face
->faceinfo
)
367 f_prev_error
= FLT_MAX
;
368 #ifdef OSG_USE_NURBS_PATCH
369 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
370 while(f_act_error
> fError
)
372 const SErrorTreeCell
* cpt_errcell
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
;
373 bool b_split_ok
= true;
376 #ifdef OSG_USE_KD_TREE
377 #ifdef OSG_ARBITRARY_SPLIT
378 if(cpt_errcell
->fSplitValue
< 0.0)
380 if(cpt_errcell
->bSplitHoriz
)
383 #ifdef OSG_ARBITRARY_SPLIT
384 const double cd_ratio
= osgMin(-cpt_errcell
->fSplitValue
, 1.0f
+ cpt_errcell
->fSplitValue
);
385 #ifdef OSG_UNION_TRI_QUAD
386 if( (pcl_face
->orig_face
[1]->coords
[0] - pcl_face
->orig_face
[0]->coords
[0]) * cd_ratio
> DCTP_EPS
* 100.0)
388 if( (pcl_face
->orig_quad
[1]->coords
[0] - pcl_face
->orig_quad
[0]->coords
[0]) * cd_ratio
> DCTP_EPS
* 100.0)
391 #ifdef OSG_UNION_TRI_QUAD
392 if( (pcl_face
->orig_face
[1]->coords
[0] - pcl_face
->orig_face
[0]->coords
[0]) * 0.5 > DCTP_EPS
* 100.0)
394 if( (pcl_face
->orig_quad
[1]->coords
[0] - pcl_face
->orig_quad
[0]->coords
[0]) * 0.5 > DCTP_EPS
* 100.0)
398 #ifdef OSG_ARBITRARY_SPLIT
399 pclMesh
->SubdivideQuadEW(pcl_face
, -cpt_errcell
->fSplitValue
);
401 pclMesh
->SubdivideQuadEW(pcl_face
);
411 #ifdef OSG_ARBITRARY_SPLIT
412 const double cd_ratio
= osgMin(cpt_errcell
->fSplitValue
, 1.0f
- cpt_errcell
->fSplitValue
);
413 #ifdef OSG_UNION_TRI_QUAD
414 if( (pcl_face
->orig_face
[0]->coords
[1] - pcl_face
->orig_face
[3]->coords
[1]) * cd_ratio
> DCTP_EPS
* 100.0)
416 if( (pcl_face
->orig_quad
[0]->coords
[1] - pcl_face
->orig_quad
[3]->coords
[1]) * cd_ratio
> DCTP_EPS
* 100.0)
419 #ifdef OSG_UNION_TRI_QUAD
420 if( (pcl_face
->orig_face
[0]->coords
[1] - pcl_face
->orig_face
[3]->coords
[1]) * 0.5 > DCTP_EPS
* 100.0)
422 if( (pcl_face
->orig_quad
[0]->coords
[1] - pcl_face
->orig_quad
[3]->coords
[1]) * 0.5 > DCTP_EPS
* 100.0)
426 #ifdef OSG_ARBITRARY_SPLIT
427 pclMesh
->SubdivideQuadNS(pcl_face
, cpt_errcell
->fSplitValue
);
429 pclMesh
->SubdivideQuadNS(pcl_face
);
439 SubdivideBuild(pclMesh
, pcl_face
);
440 ++ui_face_cnt
; // one new face
441 f_prev_error
= f_act_error
;
442 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
446 f_prev_error
= f_act_error
;
450 pclMesh
->SubdivideQuad(pcl_face
);
451 SubdivideBuild(pclMesh
, pcl_face
);
452 ui_face_cnt
+= 3; // three new faces
453 f_prev_error
= f_act_error
;
454 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
458 if( (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
)
460 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
461 while(f_act_error
> fError
)
463 pclMesh
->SubdivideQuad(pcl_face
);
464 SubdivideBuild(pclMesh
, pcl_face
);
465 ui_face_cnt
+= 3; // three new faces
466 f_prev_error
= f_act_error
;
467 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptErrorCell
->fError
;
472 f_act_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptBPCell
->fError
;
473 f_prev_error
= (static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
) )->ptBPCell
->fPrevError
;
476 if(f_act_error
> m_fMaxError
)
478 m_fMaxError
= f_act_error
;
479 rfMinError
= f_act_error
;
481 if(f_prev_error
< rfMaxError
)
483 rfMaxError
= f_prev_error
;
488 // delete faceinfo and constructed bezier patches
489 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
491 pcl_face
= pclMesh
->faces
[ui_face
];
492 pt_finfo
= static_cast<SFaceTreeCell
*>(pcl_face
->faceinfo
);
495 if(pt_finfo
->bOwnSurface
)
497 #ifdef OSG_USE_NURBS_PATCH
498 delete pt_finfo
->pclBSplineSurface
;
500 delete pt_finfo
->pclBezierSurface
;
504 pcl_face
->faceinfo
= NULL
;
508 pclMesh->removeFace( ui_face );
514 // std::cerr << "build " << ui_face_cnt << " faces" << std::endl;
516 /* if( pclMesh->faces.size( ) >= 1000 )
518 if( fError > m_fErrorCutoff )
520 std::cerr << "reduce error cutoff: " << m_fErrorCutoff << " -> " << fError << std::endl;
521 m_fErrorCutoff = fError;
524 if( fError <= m_fErrorCutoff )
529 // std::cerr << "done" << std::endl;
536 /*#ifdef OSG_ARBITRARY_SPLIT
537 void CErrorQuadTree::CalculatePoints( std::vector< Vec2d > *pvclInsert, std::vector< Vec2d > *pvclDelete,
538 BSplineTensorSurface *pclPatch,
539 float fError, float &rfMinError, float &rfMaxError )
541 std::vector< SFaceTreeCell > vt_build_cells;
542 unsigned int ui_cell;
543 unsigned int ui_cell_cnt = 1;
548 std::vector< BSplineTensorSurface > vcl_surfaces;
551 if( fError < m_fErrorCutoff )
553 fError = m_fErrorCutoff;
556 pvclInsert->clear( );
557 pvclDelete->clear( );
559 if( m_fMaxError >= 0.0 )
561 f_old_error = rfMinError;
562 if( fError <= rfMinError )
566 else if( fError >= rfMaxError )
577 f_old_error = FLT_MAX;
581 if( m_ptRoot == NULL )
583 m_ptRoot = new SErrorTreeCell;
584 m_ptRoot->ptChildren = NULL;
585 m_ptRoot->fError = -1.0;
588 vt_build_cells.resize( 1 );
589 vt_build_cells[ 0 ].bOwnSurface = false;
590 vt_build_cells[ 0 ].pclBSplineSurface = pclPatch;
591 vt_build_cells[ 0 ].ptErrorCell = m_ptRoot;
592 pclPatch->getParameterInterval_U( vt_build_cells[ 0 ].clMin[0], vt_build_cells[ 0 ].clMax[0] );
593 pclPatch->getParameterInterval_V( vt_build_cells[ 0 ].clMin[1], vt_build_cells[ 0 ].clMax[1] );
594 ComputeError( &( vt_build_cells[ 0 ] ) );
597 rfMaxError = FLT_MAX;
599 if( ( fError >= m_fMaxError ) && ( m_fMaxError >= 0.0 ) )
601 // ok, we already have a subdivision for that error...
602 for( ui_cell = 0; ui_cell < ui_cell_cnt; ++ui_cell )
604 f_prev_error = FLT_MAX;
605 f_act_error = vt_build_cells[ ui_cell ].ptErrorCell->fError;
606 while( f_act_error > fError )
608 vt_build_cells.resize( ui_cell_cnt + 1 );
609 vt_build_cells[ ui_cell_cnt ].bOwnSurface = false;
610 vt_build_cells[ ui_cell_cnt ].pclBSplineSurface = NULL;
611 vt_build_cells[ ui_cell_cnt ].clMin = vt_build_cells[ ui_cell ].clMin;
612 vt_build_cells[ ui_cell_cnt ].clMax = vt_build_cells[ ui_cell ].clMax;
613 vt_build_cells[ ui_cell ].bOwnSurface = false;
614 vt_build_cells[ ui_cell ].pclBSplineSurface = NULL;
615 if( vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue < 0.0 )
617 vt_build_cells[ ui_cell ].clMax[0] =
618 vt_build_cells[ ui_cell ].clMin[0]
619 - ( vt_build_cells[ ui_cell ].clMax[0] - vt_build_cells[ ui_cell ].clMin[0] )
620 * vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue;
621 vt_build_cells[ ui_cell_cnt ].clMin[0] = vt_build_cells[ ui_cell ].clMax[0];
625 vt_build_cells[ ui_cell ].clMax[1] =
626 vt_build_cells[ ui_cell ].clMin[1]
627 + ( vt_build_cells[ ui_cell ].clMax[1] - vt_build_cells[ ui_cell ].clMin[1] )
628 * vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue;
629 vt_build_cells[ ui_cell_cnt ].clMin[1] = vt_build_cells[ ui_cell ].clMax[1];
631 // set new error cells
632 vt_build_cells[ ui_cell_cnt ].ptErrorCell = &( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 1 ] );
633 vt_build_cells[ ui_cell ].ptErrorCell = &( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 0 ] );
634 if( ( b_insert ) && ( f_act_error >= f_old_error ) )
637 if( scl_check.insert( vt_build_cells[ ui_cell ].clMax ).second )
639 pvclInsert->push_back( vt_build_cells[ ui_cell ].clMax );
641 if( scl_check.insert( vt_build_cells[ ui_cell_cnt ].clMin ).second )
643 pvclInsert->push_back( vt_build_cells[ ui_cell_cnt ].clMin );
648 scl_check.insert( vt_build_cells[ ui_cell ].clMax );
649 scl_check.insert( vt_build_cells[ ui_cell_cnt ].clMin );
651 ++ui_cell_cnt; // one new face
652 f_prev_error = f_act_error;
653 f_act_error = vt_build_cells[ ui_cell ].ptErrorCell->fError;
655 if( f_act_error > rfMinError )
657 rfMinError = f_act_error;
659 if( f_prev_error < rfMaxError )
661 rfMaxError = f_prev_error;
666 while( f_act_error > f_old_error )
668 vt_build_cells.resize( ui_cell_cnt + 1 );
669 vt_build_cells[ ui_cell_cnt ].bOwnSurface = false;
670 vt_build_cells[ ui_cell_cnt ].pclBSplineSurface = NULL;
671 vt_build_cells[ ui_cell_cnt ].clMin = vt_build_cells[ ui_cell ].clMin;
672 vt_build_cells[ ui_cell_cnt ].clMax = vt_build_cells[ ui_cell ].clMax;
673 vt_build_cells[ ui_cell ].bOwnSurface = false;
674 vt_build_cells[ ui_cell ].pclBSplineSurface = NULL;
675 if( vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue < 0.0 )
677 vt_build_cells[ ui_cell ].clMax[0] =
678 vt_build_cells[ ui_cell ].clMin[0]
679 - ( vt_build_cells[ ui_cell ].clMax[0] - vt_build_cells[ ui_cell ].clMin[0] )
680 * vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue;
681 vt_build_cells[ ui_cell_cnt ].clMin[0] = vt_build_cells[ ui_cell ].clMax[0];
685 vt_build_cells[ ui_cell ].clMax[1] =
686 vt_build_cells[ ui_cell ].clMin[1]
687 + ( vt_build_cells[ ui_cell ].clMax[1] - vt_build_cells[ ui_cell ].clMin[1] )
688 * vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue;
689 vt_build_cells[ ui_cell_cnt ].clMin[1] = vt_build_cells[ ui_cell ].clMax[1];
691 // set new error cells
692 vt_build_cells[ ui_cell_cnt ].ptErrorCell = &( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 1 ] );
693 vt_build_cells[ ui_cell ].ptErrorCell = &( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 0 ] );
694 if( scl_check.insert( vt_build_cells[ ui_cell ].clMax ).second )
696 pvclDelete->push_back( vt_build_cells[ ui_cell ].clMax );
698 if( scl_check.insert( vt_build_cells[ ui_cell_cnt ].clMin ).second )
700 pvclDelete->push_back( vt_build_cells[ ui_cell_cnt ].clMin );
702 ++ui_cell_cnt; // one new face
703 f_act_error = vt_build_cells[ ui_cell ].ptErrorCell->fError;
707 vt_build_cells.clear( );
711 // we need to build a new Kd-tree
712 for( ui_cell = 0; ui_cell < ui_cell_cnt; ++ui_cell )
714 f_prev_error = FLT_MAX;
715 f_act_error = vt_build_cells[ ui_cell ].ptErrorCell->fError;
716 while( f_act_error > fError )
718 if( vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue < 0.0 )
720 vt_build_cells[ ui_cell ].pclBSplineSurface->subDivisionU(
721 vcl_surfaces, -vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue );
725 vt_build_cells[ ui_cell ].pclBSplineSurface->subDivisionV(
726 vcl_surfaces, vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue );
728 vt_build_cells.resize( ui_cell_cnt + 1 );
729 vt_build_cells[ ui_cell_cnt ].bOwnSurface = true;
730 vt_build_cells[ ui_cell_cnt ].pclBSplineSurface = new BSplineTensorSurface;
731 *( vt_build_cells[ ui_cell_cnt ].pclBSplineSurface ) = vcl_surfaces[ 1 ];
732 vt_build_cells[ ui_cell_cnt ].clMin = vt_build_cells[ ui_cell ].clMin;
733 vt_build_cells[ ui_cell_cnt ].clMax = vt_build_cells[ ui_cell ].clMax;
734 if( vt_build_cells[ ui_cell ].bOwnSurface )
736 delete vt_build_cells[ ui_cell ].pclBSplineSurface;
738 vt_build_cells[ ui_cell ].bOwnSurface = true;
739 vt_build_cells[ ui_cell ].pclBSplineSurface = new BSplineTensorSurface;
740 *( vt_build_cells[ ui_cell ].pclBSplineSurface ) = vcl_surfaces[ 0 ];
741 std::cerr << vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue << std::endl;
742 std::cerr << vt_build_cells[ ui_cell ].clMin << vt_build_cells[ ui_cell ].clMax << std::endl;
743 if( vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue < 0.0 )
745 vt_build_cells[ ui_cell ].clMax[0] =
746 vt_build_cells[ ui_cell ].clMin[0]
747 - ( vt_build_cells[ ui_cell ].clMax[0] - vt_build_cells[ ui_cell ].clMin[0] )
748 * vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue;
749 vt_build_cells[ ui_cell_cnt ].clMin[0] = vt_build_cells[ ui_cell ].clMax[0];
753 vt_build_cells[ ui_cell ].clMax[1] =
754 vt_build_cells[ ui_cell ].clMin[1]
755 + ( vt_build_cells[ ui_cell ].clMax[1] - vt_build_cells[ ui_cell ].clMin[1] )
756 * vt_build_cells[ ui_cell ].ptErrorCell->fSplitValue;
757 vt_build_cells[ ui_cell_cnt ].clMin[1] = vt_build_cells[ ui_cell ].clMax[1];
759 std::cerr << vt_build_cells[ ui_cell ].clMin << vt_build_cells[ ui_cell ].clMax << std::endl;
760 std::cerr << vt_build_cells[ ui_cell_cnt ].clMin << vt_build_cells[ ui_cell_cnt ].clMax << std::endl << std::endl;
761 // set new error cells
762 if( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren == NULL )
764 vt_build_cells[ ui_cell ].ptErrorCell->ptChildren = new SErrorTreeCell[ 2 ];
765 vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 0 ].ptChildren = NULL;
766 vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 0 ].fError = -1.0;
767 vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 1 ].ptChildren = NULL;
768 vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 1 ].fError = -1.0;
770 vt_build_cells[ ui_cell_cnt ].ptErrorCell = &( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 1 ] );
771 vt_build_cells[ ui_cell ].ptErrorCell = &( vt_build_cells[ ui_cell ].ptErrorCell->ptChildren[ 0 ] );
773 ComputeError( &( vt_build_cells[ ui_cell ] ) );
774 ComputeError( &( vt_build_cells[ ui_cell_cnt ] ) );
776 if( scl_check.insert( vt_build_cells[ ui_cell ].clMax ).second )
778 pvclInsert->push_back( vt_build_cells[ ui_cell ].clMax );
780 if( scl_check.insert( vt_build_cells[ ui_cell_cnt ].clMin ).second )
782 pvclInsert->push_back( vt_build_cells[ ui_cell_cnt ].clMin );
784 ++ui_cell_cnt; // one new face
785 f_prev_error = f_act_error;
786 f_act_error = vt_build_cells[ ui_cell ].ptErrorCell->fError;
788 if( f_act_error > rfMinError )
790 rfMinError = f_act_error;
792 if( f_prev_error < rfMaxError )
794 rfMaxError = f_prev_error;
798 // delete build cells and constructed bspline patches
799 for( ui_cell = 0; ui_cell < ui_cell_cnt; ++ui_cell )
801 if( vt_build_cells[ ui_cell ].bOwnSurface )
803 vt_build_cells[ ui_cell ].pclBSplineSurface;
806 vt_build_cells.clear( );
811 #ifdef OSG_ONE_CHILD_PTR
812 void CErrorQuadTree::DeleteNode(SErrorTreeCell
*pclNode
)
814 if(pclNode
->ptChildren
)
816 DeleteNode(&(pclNode
->ptChildren
[0]) );
817 DeleteNode(&(pclNode
->ptChildren
[1]) );
818 #ifndef OSG_USE_KD_TREE
819 DeleteNode(&(pclNode
->ptChildren
[2]) );
820 DeleteNode(&(pclNode
->ptChildren
[3]) );
822 delete[] pclNode
->ptChildren
;
823 pclNode
->ptChildren
= NULL
;
827 void CErrorQuadTree::DeleteNode(SErrorTreeCell
*&rpclNode
)
829 if(rpclNode
->aptChildren
[0])
831 DeleteNode(rpclNode
->aptChildren
[0]);
832 DeleteNode(rpclNode
->aptChildren
[1]);
833 #ifndef OSG_USE_KD_TREE
834 DeleteNode(rpclNode
->aptChildren
[2]);
835 DeleteNode(rpclNode
->aptChildren
[3]);
844 //#ifndef OSG_ARBITRARY_SPLIT
845 void CErrorQuadTree::SetInitialCells(DCTPMesh
*pclMesh
, float fError
,
846 #ifdef OSG_USE_NURBS_PATCH
847 #ifdef OSG_ARBITRARY_SPLIT
848 BSplineTensorSurface
*pclPatch
,
849 const Vec2d cclMinParam
, const Vec2d cclMaxParam
)
851 BSplineTensorSurface
* pclPatch
)
854 std::vector
<std::vector
<BezierTensorSurface
> > *pvvclPatches
,
855 const std::vector
<double> *cpvdIntervalsU
,
856 const std::vector
<double> *cpvdIntervalsV
)
859 #ifdef OSG_USE_NURBS_PATCH
864 Vec3d acl_edge_points
[4];
866 SFaceTreeCell
*pt_finfo
;
868 #ifdef OSG_ARBITRARY_SPLIT
869 d_min_x
= cclMinParam
[0];
870 d_min_y
= cclMinParam
[1];
871 d_max_x
= cclMaxParam
[0];
872 d_max_y
= cclMaxParam
[1];
874 pclPatch
->getParameterInterval_U(d_min_x
, d_max_x
);
875 pclPatch
->getParameterInterval_V(d_min_y
, d_max_y
);
877 acl_edge_points
[0][0] = d_min_x
;
878 acl_edge_points
[1][0] = d_max_x
;
879 acl_edge_points
[2][0] = d_max_x
;
880 acl_edge_points
[3][0] = d_min_x
;
881 acl_edge_points
[0][1] = d_max_y
;
882 acl_edge_points
[1][1] = d_max_y
;
883 acl_edge_points
[2][1] = d_min_y
;
884 acl_edge_points
[3][1] = d_min_y
;
885 acl_edge_points
[0][2] = 0.0;
886 acl_edge_points
[1][2] = 0.0;
887 acl_edge_points
[2][2] = 0.0;
888 acl_edge_points
[3][2] = 0.0;
892 m_ptRoot
= new SErrorTreeCell
;
893 #ifdef OSG_ONE_CHILD_PTR
894 m_ptRoot
->ptChildren
= NULL
;
896 m_ptRoot
->aptChildren
[0] = NULL
;
897 m_ptRoot
->aptChildren
[1] = NULL
;
898 m_ptRoot
->aptChildren
[2] = NULL
;
899 m_ptRoot
->aptChildren
[3] = NULL
;
901 m_ptRoot
->fError
= -1.0;
904 pcl_face
= pclMesh
->AddQuad(acl_edge_points
[0], acl_edge_points
[1],
905 acl_edge_points
[2], acl_edge_points
[3], 0.0);
906 pt_finfo
= new SFaceTreeCell
;
907 pt_finfo
->bOwnSurface
= false;
908 #ifdef OSG_ARBITRARY_SPLIT
909 pt_finfo
->pclBSplineSurface
= NULL
;
911 pt_finfo
->pclBSplineSurface
= pclPatch
;
913 pt_finfo
->ptErrorCell
= m_ptRoot
;
914 pcl_face
->faceinfo
= static_cast<void*>(pt_finfo
);
916 const unsigned int cui_u_size
= cpvdIntervalsU
->size() - 1;
917 const unsigned int cui_v_size
= cpvdIntervalsV
->size() - 1;
918 Vec3d acl_edge_points
[4];
922 SFaceTreeCell
*pt_finfo
;
923 unsigned int ui_face
;
924 unsigned int ui_face_cnt
;
927 acl_edge_points
[0][2] = 1.0;
928 acl_edge_points
[1][2] = 1.0;
929 acl_edge_points
[2][2] = 1.0;
930 acl_edge_points
[3][2] = 1.0;
932 if(m_vvptRoot
.size() == 0)
934 // std::cerr << "new QuadTree" << std::endl;
935 m_vvptRoot
.resize(cui_u_size
);
937 for(ui_u
= 0; ui_u
< cui_u_size
; ++ui_u
)
939 m_vvptRoot
[ui_u
].resize(cui_v_size
);
941 for(ui_v
= 0; ui_v
< cui_v_size
; ++ui_v
)
943 m_vvptRoot
[ui_u
][ui_v
] = new SErrorTreeCell
;
944 #ifdef OSG_ONE_CHILD_PTR
945 m_vvptRoot
[ui_u
][ui_v
]->ptChildren
= NULL
;
947 m_vvptRoot
[ui_u
][ui_v
]->aptChildren
[0] = NULL
;
948 m_vvptRoot
[ui_u
][ui_v
]->aptChildren
[1] = NULL
;
949 m_vvptRoot
[ui_u
][ui_v
]->aptChildren
[2] = NULL
;
950 m_vvptRoot
[ui_u
][ui_v
]->aptChildren
[3] = NULL
;
952 m_vvptRoot
[ui_u
][ui_v
]->fError
= -1.0;
956 ComputeBPTree(pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
959 acl_edge_points
[0][0] = (*cpvdIntervalsU
)[0];
960 acl_edge_points
[1][0] = (*cpvdIntervalsU
)[cui_u_size
];
961 acl_edge_points
[2][0] = (*cpvdIntervalsU
)[cui_u_size
];
962 acl_edge_points
[3][0] = (*cpvdIntervalsU
)[0];
963 acl_edge_points
[0][1] = (*cpvdIntervalsV
)[cui_v_size
];
964 acl_edge_points
[1][1] = (*cpvdIntervalsV
)[cui_v_size
];
965 acl_edge_points
[2][1] = (*cpvdIntervalsV
)[0];
966 acl_edge_points
[3][1] = (*cpvdIntervalsV
)[0];
967 pcl_face
= pclMesh
->AddQuad(acl_edge_points
[0], acl_edge_points
[1],
968 acl_edge_points
[2], acl_edge_points
[3], 0.0);
969 pt_finfo
= new SFaceTreeCell
;
970 pt_finfo
->bOwnSurface
= false;
971 pt_finfo
->pclBezierSurface
= NULL
;
972 pt_finfo
->ptErrorCell
= NULL
;
973 pt_finfo
->ptBPCell
= m_ptBPRoot
;
974 pcl_face
->faceinfo
= ( void* ) pt_finfo
;
978 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
980 pcl_face
= pclMesh
->faces
[ui_face
];
981 if( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
)
983 f_act_error
= ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->fError
;
984 while(f_act_error
> fError
)
986 if( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->aptChildren
[1])
990 pclMesh
->SubdivideQuad(pcl_face
);
991 SubdivideNode(pclMesh
, pcl_face
);
994 else if( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->aptChildren
[0])
998 pclMesh
->SubdivideQuadNS(pcl_face
);
999 SubdivideNode(pclMesh
, pcl_face
);
1002 else if( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->aptChildren
[2])
1005 pclMesh
->SubdivideQuadEW(pcl_face
);
1006 SubdivideNode(pclMesh
, pcl_face
);
1009 if( ( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
) &&
1010 ( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->aptChildren
[3]) )
1012 f_act_error
= ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->fError
;
1020 if( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
== NULL
)
1022 delete ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
);
1023 pcl_face
->faceinfo
= NULL
;
1027 for(ui_face
= 0; ui_face
< ui_face_cnt
; ++ui_face
)
1029 pcl_face
= pclMesh
->faces
[ui_face
];
1030 if(pcl_face
->faceinfo
)
1032 /* std::cerr << "quad:";
1033 std::cerr << pcl_face->orig_quad[ 0 ]->coords << " ";
1034 std::cerr << pcl_face->orig_quad[ 1 ]->coords << " ";
1035 std::cerr << pcl_face->orig_quad[ 2 ]->coords << " ";
1036 std::cerr << pcl_face->orig_quad[ 3 ]->coords << std::endl;
1037 std::cerr << ( ( SFaceTreeCell* ) pcl_face->faceinfo )->ptBPCell->uiLeft << " - ";
1038 std::cerr << ( ( SFaceTreeCell* ) pcl_face->faceinfo )->ptBPCell->uiRight << " , ";
1039 std::cerr << ( ( SFaceTreeCell* ) pcl_face->faceinfo )->ptBPCell->uiBottom << " - ";
1040 std::cerr << ( ( SFaceTreeCell* ) pcl_face->faceinfo )->ptBPCell->uiTop << std::endl;*/
1041 #ifdef OSG_UNION_TRI_QUAD
1042 pclMesh
->MoveVertex(
1043 pcl_face
->orig_face
[0],
1044 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiLeft
],
1045 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiTop
+ 1],
1047 pclMesh
->MoveVertex(
1048 pcl_face
->orig_face
[1],
1049 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiRight
+ 1],
1050 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiTop
+ 1],
1052 pclMesh
->MoveVertex(
1053 pcl_face
->orig_face
[2],
1054 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiRight
+ 1],
1055 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiBottom
],
1057 pclMesh
->MoveVertex(
1058 pcl_face
->orig_face
[3],
1059 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiLeft
],
1060 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiBottom
],
1063 pclMesh
->MoveVertex(
1064 pcl_face
->orig_quad
[0],
1065 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiLeft
],
1066 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiTop
+ 1],
1068 pclMesh
->MoveVertex(
1069 pcl_face
->orig_quad
[1],
1070 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiRight
+ 1],
1071 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiTop
+ 1],
1073 pclMesh
->MoveVertex(
1074 pcl_face
->orig_quad
[2],
1075 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiRight
+ 1],
1076 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiBottom
],
1078 pclMesh
->MoveVertex(
1079 pcl_face
->orig_quad
[3],
1080 Vec3d( (*cpvdIntervalsU
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiLeft
],
1081 (*cpvdIntervalsV
)[( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiBottom
],
1084 /* std::cerr << "moved to:";
1085 std::cerr << pcl_face->orig_quad[ 0 ]->coords << " ";
1086 std::cerr << pcl_face->orig_quad[ 1 ]->coords << " ";
1087 std::cerr << pcl_face->orig_quad[ 2 ]->coords << " ";
1088 std::cerr << pcl_face->orig_quad[ 3 ]->coords << std::endl;*/
1089 if( ( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->aptChildren
[3] == NULL
) &&
1090 ( ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->fError
> fError
) )
1093 ui_u
= ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiLeft
;
1094 ui_v
= ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
)->ptBPCell
->uiBottom
;
1095 // std::cerr << ui_u << "," << ui_v << std::endl;
1096 pt_finfo
= ( ( SFaceTreeCell
* ) pcl_face
->faceinfo
);
1097 pt_finfo
->bOwnSurface
= false;
1098 pt_finfo
->pclBezierSurface
= &( (*pvvclPatches
)[ui_u
][ui_v
]);
1099 pt_finfo
->ptErrorCell
= m_vvptRoot
[ui_u
][ui_v
];
1100 pt_finfo
->ptBPCell
= NULL
;
1101 // pcl_face->faceinfo = ( void* ) pt_finfo;
1110 void CErrorQuadTree::SubdivideNode(DCTPMesh
*pclMesh
, DCTPFace
*pclFace
)
1112 const unsigned int cui_face_cnt
= UInt32(pclMesh
->faces
.size());
1113 unsigned int ui_child
;
1114 #ifdef OSG_USE_KD_TREE
1115 DCTPFace
*apcl_faces
[2];
1117 DCTPFace
*apcl_faces
[4];
1119 SFaceTreeCell
*pcl_old_node
= static_cast<SFaceTreeCell
*>(pclFace
->faceinfo
);
1120 SFaceTreeCell
*pcl_new_node
;
1122 pclFace
->faceinfo
= NULL
;
1124 #ifdef OSG_USE_NURBS_PATCH
1125 apcl_faces
[0] = pclFace
;
1126 #ifdef OSG_USE_KD_TREE
1127 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 1];
1129 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 3];
1130 apcl_faces
[2] = pclMesh
->faces
[cui_face_cnt
- 2];
1131 apcl_faces
[3] = pclMesh
->faces
[cui_face_cnt
- 1];
1134 #ifdef OSG_USE_KD_TREE
1136 for(ui_child
= 0; ui_child
< 2; ++ui_child
)
1139 for(ui_child
= 0; ui_child
< 4; ++ui_child
)
1142 pcl_new_node
= new SFaceTreeCell
;
1143 // std::cerr << "subdivide with ErrorCell" << std::endl;
1144 #ifdef OSG_ONE_CHILD_PTR
1145 pcl_new_node
->ptErrorCell
= &(pcl_old_node
->ptErrorCell
->ptChildren
[ui_child
]);
1147 pcl_new_node
->ptErrorCell
= pcl_old_node
->ptErrorCell
->aptChildren
[ui_child
];
1149 pcl_new_node
->pclBSplineSurface
= NULL
;
1150 pcl_new_node
->bOwnSurface
= false;
1151 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1155 if(pcl_old_node
->ptErrorCell
)
1157 apcl_faces
[0] = pclFace
;
1158 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 3];
1159 apcl_faces
[2] = pclMesh
->faces
[cui_face_cnt
- 2];
1160 apcl_faces
[3] = pclMesh
->faces
[cui_face_cnt
- 1];
1162 for(ui_child
= 0; ui_child
< 4; ++ui_child
)
1164 pcl_new_node
= new SFaceTreeCell
;
1165 // std::cerr << "subdivide with ErrorCell" << std::endl;
1166 #ifdef OSG_ONE_CHILD_PTR
1167 pcl_new_node
->ptErrorCell
= &(pcl_old_node
->ptErrorCell
->ptChildren
[ui_child
]);
1169 pcl_new_node
->ptErrorCell
= pcl_old_node
->ptErrorCell
->aptChildren
[ui_child
];
1171 pcl_new_node
->ptBPCell
= NULL
;
1172 pcl_new_node
->pclBezierSurface
= NULL
;
1173 pcl_new_node
->bOwnSurface
= false;
1174 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1177 else if(pcl_old_node
->ptBPCell
->aptChildren
[1])
1181 apcl_faces
[0] = pclFace
;
1182 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 3];
1183 apcl_faces
[2] = pclMesh
->faces
[cui_face_cnt
- 2];
1184 apcl_faces
[3] = pclMesh
->faces
[cui_face_cnt
- 1];
1186 for(ui_child
= 0; ui_child
< 4; ++ui_child
)
1188 pcl_new_node
= new SFaceTreeCell
;
1189 // std::cerr << "subdivide with BPCell" << std::endl;
1190 pcl_new_node
->ptErrorCell
= NULL
;
1191 pcl_new_node
->ptBPCell
= pcl_old_node
->ptBPCell
->aptChildren
[ui_child
];
1192 /* std::cerr << pcl_new_node->ptBPCell->uiLeft << " - ";
1193 std::cerr << pcl_new_node->ptBPCell->uiRight << " , ";
1194 std::cerr << pcl_new_node->ptBPCell->uiBottom << " - ";
1195 std::cerr << pcl_new_node->ptBPCell->uiTop << std::endl;
1196 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 0 ]->coords << " ";
1197 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 1 ]->coords << " ";
1198 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 2 ]->coords << " ";
1199 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 3 ]->coords << std::endl;*/
1200 pcl_new_node
->pclBezierSurface
= NULL
;
1201 pcl_new_node
->bOwnSurface
= false;
1202 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1205 else if(pcl_old_node
->ptBPCell
->aptChildren
[0])
1209 apcl_faces
[0] = pclFace
;
1210 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 1];
1212 for(ui_child
= 0; ui_child
< 2; ++ui_child
)
1214 pcl_new_node
= new SFaceTreeCell
;
1215 // std::cerr << "subdivide with BPCell" << std::endl;
1216 pcl_new_node
->ptErrorCell
= NULL
;
1217 pcl_new_node
->ptBPCell
= pcl_old_node
->ptBPCell
->aptChildren
[3 * ui_child
];
1218 /* std::cerr << pcl_new_node->ptBPCell->uiLeft << " - ";
1219 std::cerr << pcl_new_node->ptBPCell->uiRight << " , ";
1220 std::cerr << pcl_new_node->ptBPCell->uiBottom << " - ";
1221 std::cerr << pcl_new_node->ptBPCell->uiTop << std::endl;
1222 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 0 ]->coords << " ";
1223 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 1 ]->coords << " ";
1224 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 2 ]->coords << " ";
1225 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 3 ]->coords << std::endl;*/
1226 pcl_new_node
->pclBezierSurface
= NULL
;
1227 pcl_new_node
->bOwnSurface
= false;
1228 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1234 apcl_faces
[0] = pclFace
;
1235 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 1];
1237 for(ui_child
= 0; ui_child
< 2; ++ui_child
)
1239 pcl_new_node
= new SFaceTreeCell
;
1240 // std::cerr << "subdivide with BPCell" << std::endl;
1241 pcl_new_node
->ptErrorCell
= NULL
;
1242 pcl_new_node
->ptBPCell
= pcl_old_node
->ptBPCell
->aptChildren
[3 - ui_child
];
1243 /* std::cerr << pcl_new_node->ptBPCell->uiLeft << " - ";
1244 std::cerr << pcl_new_node->ptBPCell->uiRight << " , ";
1245 std::cerr << pcl_new_node->ptBPCell->uiBottom << " - ";
1246 std::cerr << pcl_new_node->ptBPCell->uiTop << std::endl;
1247 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 0 ]->coords << " ";
1248 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 1 ]->coords << " ";
1249 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 2 ]->coords << " ";
1250 std::cerr << apcl_faces[ ui_child ]->orig_quad[ 3 ]->coords << std::endl;*/
1251 pcl_new_node
->pclBezierSurface
= NULL
;
1252 pcl_new_node
->bOwnSurface
= false;
1253 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1258 delete pcl_old_node
;
1262 void CErrorQuadTree::SubdivideBuild(DCTPMesh
*pclMesh
, DCTPFace
*pclFace
)
1264 const unsigned int cui_face_cnt
= UInt32(pclMesh
->faces
.size());
1265 unsigned int ui_child
;
1266 #ifdef OSG_USE_KD_TREE
1267 DCTPFace
*apcl_faces
[2];
1269 DCTPFace
*apcl_faces
[4];
1271 SFaceTreeCell
*pcl_old_node
= static_cast<SFaceTreeCell
*>(pclFace
->faceinfo
);
1272 SFaceTreeCell
*pcl_new_node
;
1273 #ifdef OSG_USE_NURBS_PATCH
1274 #ifdef OSG_USE_KD_TREE
1275 std::vector
<BSplineTensorSurface
> vcl_surfaces
;
1277 std::vector
<std::vector
<BSplineTensorSurface
> > vvcl_surfaces
;
1280 #ifdef OSG_USE_KD_TREE
1281 std::vector
<BezierTensorSurface
> vcl_surfaces
;
1283 std::vector
<std::vector
<BezierTensorSurface
> > vvcl_surfaces
;
1287 apcl_faces
[0] = pclFace
;
1288 #ifdef OSG_USE_KD_TREE
1289 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 1];
1291 apcl_faces
[1] = pclMesh
->faces
[cui_face_cnt
- 3];
1292 apcl_faces
[2] = pclMesh
->faces
[cui_face_cnt
- 2];
1293 apcl_faces
[3] = pclMesh
->faces
[cui_face_cnt
- 1];
1296 pclFace
->faceinfo
= NULL
;
1297 #ifdef OSG_USE_NURBS_PATCH
1298 #ifdef OSG_USE_KD_TREE
1299 #ifdef OSG_ARBITRARY_SPLIT
1300 if(pcl_old_node
->ptErrorCell
->fSplitValue
< 0.0)
1302 pcl_old_node
->pclBSplineSurface
->subDivisionU(vcl_surfaces
, -pcl_old_node
->ptErrorCell
->fSplitValue
);
1306 pcl_old_node
->pclBSplineSurface
->subDivisionV(vcl_surfaces
, pcl_old_node
->ptErrorCell
->fSplitValue
);
1309 if(pcl_old_node
->ptErrorCell
->bSplitHoriz
)
1311 pcl_old_node
->pclBSplineSurface
->midPointSubDivisionU(vcl_surfaces
);
1315 pcl_old_node
->pclBSplineSurface
->midPointSubDivisionV(vcl_surfaces
);
1319 pcl_old_node
->pclBSplineSurface
->midPointSubDivision(vvcl_surfaces
);
1322 #ifdef OSG_USE_KD_TREE
1325 pcl_old_node
->pclBezierSurface
->midPointSubDivision(vvcl_surfaces
);
1329 #ifdef OSG_ONE_CHILD_PTR
1330 #ifdef OSG_USE_KD_TREE
1332 for(ui_child
= 0; ui_child
< 2; ++ui_child
)
1335 for(ui_child
= 0; ui_child
< 4; ++ui_child
)
1338 pcl_new_node
= new SFaceTreeCell
;
1339 pcl_new_node
->ptErrorCell
= &(pcl_old_node
->ptErrorCell
->ptChildren
[ui_child
]);
1340 pcl_new_node
->bOwnSurface
= true;
1341 #ifdef OSG_USE_NURBS_PATCH
1342 pcl_new_node
->pclBSplineSurface
= new BSplineTensorSurface
;
1343 #ifdef OSG_USE_KD_TREE
1344 (*pcl_new_node
->pclBSplineSurface
) = vcl_surfaces
[ui_child
];
1346 (*pcl_new_node
->pclBSplineSurface
) = vvcl_surfaces
[( (ui_child
+ 1) >> 1) & 1][1 - (ui_child
>> 1)];
1349 pcl_new_node
->pclBezierSurface
= new BezierTensorSurface
;
1350 #ifdef OSG_USE_KD_TREE
1351 (*pcl_new_node
->pclBezierSurface
) = vvcl_surfaces
[ui_child
];
1353 (*pcl_new_node
->pclBezierSurface
) = vvcl_surfaces
[( (ui_child
+ 1) >> 1) & 1][1 - (ui_child
>> 1)];
1356 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1359 if(pcl_old_node
->ptErrorCell
->ptChildren
== NULL
)
1361 #ifdef OSG_USE_KD_TREE
1362 pcl_old_node
->ptErrorCell
->ptChildren
= new SErrorTreeCell
[2];
1364 for(ui_child
= 0; ui_child
< 2; ++ui_child
)
1366 pcl_old_node
->ptErrorCell
->ptChildren
= new SErrorTreeCell
[4];
1368 for(ui_child
= 0; ui_child
< 4; ++ui_child
)
1371 pcl_new_node
= static_cast<SFaceTreeCell
*>(apcl_faces
[ui_child
]->faceinfo
);
1372 pcl_new_node
->ptErrorCell
= &(pcl_old_node
->ptErrorCell
->ptChildren
[ui_child
]);
1373 pcl_new_node
->ptErrorCell
->ptChildren
= NULL
;
1374 pcl_new_node
->ptErrorCell
->fError
= -1.0;
1375 ComputeError(apcl_faces
[ui_child
]);
1379 #ifdef OSG_USE_KD_TREE
1381 for(ui_child
= 0; ui_child
< 2; ++ui_child
)
1384 for(ui_child
= 0; ui_child
< 4; ++ui_child
)
1387 pcl_new_node
= new SFaceTreeCell
;
1388 pcl_new_node
->ptErrorCell
= pcl_old_node
->ptErrorCell
->aptChildren
[ui_child
];
1389 pcl_new_node
->bOwnSurface
= true;
1390 pcl_new_node
->pclBezierSurface
= new BezierTensorSurface
;
1391 (*pcl_new_node
->pclBezierSurface
) = vvcl_surfaces
[( (ui_child
+ 1) >> 1) & 1][1 - (ui_child
>> 1)];
1392 apcl_faces
[ui_child
]->faceinfo
= static_cast<void*>(pcl_new_node
);
1393 if(pcl_new_node
->ptErrorCell
== NULL
)
1395 pcl_old_node
->ptErrorCell
->aptChildren
[ui_child
] = new SErrorTreeCell
;
1396 pcl_new_node
->ptErrorCell
= pcl_old_node
->ptErrorCell
->aptChildren
[ui_child
];
1397 pcl_new_node
->ptErrorCell
->aptChildren
[0] = NULL
;
1398 pcl_new_node
->ptErrorCell
->aptChildren
[1] = NULL
;
1399 #ifndef OSG_USE_KD_TREE
1400 pcl_new_node
->ptErrorCell
->aptChildren
[2] = NULL
;
1401 pcl_new_node
->ptErrorCell
->aptChildren
[3] = NULL
;
1403 pcl_new_node
->ptErrorCell
->fError
= -1.0;
1404 ComputeError(apcl_faces
[ui_child
]);
1409 /* ( SFaceTreeCell* )( apcl_faces[ 0 ]->faceinfo )->pclBezierSurface = vvcl_surfaces[ 0 ][ 1 ];
1410 ( SFaceTreeCell* )( apcl_faces[ 1 ]->faceinfo )->pclBezierSurface = vvcl_surfaces[ 1 ][ 1 ];
1411 ( SFaceTreeCell* )( apcl_faces[ 2 ]->faceinfo )->pclBezierSurface = vvcl_surfaces[ 1 ][ 0 ];
1412 ( SFaceTreeCell* )( apcl_faces[ 3 ]->faceinfo )->pclBezierSurface = vvcl_surfaces[ 0 ][ 0 ];*/
1414 if(pcl_old_node
->bOwnSurface
)
1416 #ifdef OSG_USE_NURBS_PATCH
1417 delete pcl_old_node
->pclBSplineSurface
;
1419 delete pcl_old_node
->pclBezierSurface
;
1422 delete pcl_old_node
;
1427 /*#ifdef OSG_ARBITRARY_SPLIT
1428 void CErrorQuadTree::ComputeError( SFaceTreeCell *ptCell )
1430 void CErrorQuadTree::ComputeError(DCTPFace
*pclFace
)
1433 //#ifndef OSG_ARBITRARY_SPLIT
1434 SFaceTreeCell
*ptCell
= static_cast<SFaceTreeCell
*>(pclFace
->faceinfo
);
1437 if(ptCell
->ptErrorCell
->fError
>= 0.0)
1439 return; // error was already calculated
1442 if( ( (pclFace
->orig_face
[1]->coords
[0] - pclFace
->orig_face
[3]->coords
[0]) < 10.0) ||
1443 ( (pclFace
->orig_face
[1]->coords
[1] - pclFace
->orig_face
[3]->coords
[1]) < 10.0) )
1446 ptCell
->ptErrorCell
->fError
= 0.0;
1450 #ifdef OSG_USE_NURBS_PATCH
1451 BSplineTensorSurface
*pcl_surface
= ptCell
->pclBSplineSurface
;
1452 const std::vector
<double> &crvd_knot_u
= pcl_surface
->getKnotVector_U();
1453 const std::vector
<double> &crvd_knot_v
= pcl_surface
->getKnotVector_V();
1454 const unsigned int cui_dim_u
= pcl_surface
->getDimension_U();
1455 const unsigned int cui_dim_v
= pcl_surface
->getDimension_V();
1456 unsigned int ui_idx
;
1458 BezierTensorSurface
*pcl_surface
= ptCell
->pclBezierSurface
;
1460 const std::vector
<std::vector
<Vec4d
> > &crvvcl_cps
= pcl_surface
->getControlPointMatrix();
1461 const unsigned int cui_m
= UInt32(crvvcl_cps
.size()) - 1;
1462 const unsigned int cui_n
= UInt32(crvvcl_cps
[0].size()) - 1;
1464 ccl_b00
[0] = crvvcl_cps
[0][0][0] / crvvcl_cps
[0][0][3];
1465 ccl_b00
[1] = crvvcl_cps
[0][0][1] / crvvcl_cps
[0][0][3];
1466 ccl_b00
[2] = crvvcl_cps
[0][0][2] / crvvcl_cps
[0][0][3];
1468 ccl_b0n
[0] = crvvcl_cps
[0][cui_n
][0] / crvvcl_cps
[0][cui_n
][3];
1469 ccl_b0n
[1] = crvvcl_cps
[0][cui_n
][1] / crvvcl_cps
[0][cui_n
][3];
1470 ccl_b0n
[2] = crvvcl_cps
[0][cui_n
][2] / crvvcl_cps
[0][cui_n
][3];
1472 ccl_bm0
[0] = crvvcl_cps
[cui_m
][0][0] / crvvcl_cps
[cui_m
][0][3];
1473 ccl_bm0
[1] = crvvcl_cps
[cui_m
][0][1] / crvvcl_cps
[cui_m
][0][3];
1474 ccl_bm0
[2] = crvvcl_cps
[cui_m
][0][2] / crvvcl_cps
[cui_m
][0][3];
1476 ccl_bmn
[0] = crvvcl_cps
[cui_m
][cui_n
][0] / crvvcl_cps
[cui_m
][cui_n
][3];
1477 ccl_bmn
[1] = crvvcl_cps
[cui_m
][cui_n
][1] / crvvcl_cps
[cui_m
][cui_n
][3];
1478 ccl_bmn
[2] = crvvcl_cps
[cui_m
][cui_n
][2] / crvvcl_cps
[cui_m
][cui_n
][3];
1484 #ifndef OSG_USE_NURBS_PATCH
1485 const double cd_rn
= 1.0 / cui_n
;
1486 const double cd_rm
= 1.0 / cui_m
;
1490 #ifndef OSG_USE_NURBS_PATCH
1491 const Vec3d ccl_dcx0
= (ccl_bm0
- ccl_b00
) * cd_rm
;
1492 const Vec3d ccl_dcxn
= (ccl_bmn
- ccl_b0n
) * cd_rm
;
1495 #ifndef OSG_USE_NURBS_PATCH
1496 const Vec3d ccl_dc0x
= (ccl_b0n
- ccl_b00
) * cd_rn
;
1497 const Vec3d ccl_dcmx
= (ccl_bmn
- ccl_bm0
) * cd_rn
;
1503 #ifdef OSG_USE_NURBS_PATCH
1507 #ifdef OSG_ARBITRARY_SPLIT
1519 #ifndef OSG_USE_NURBS_PATCH
1531 double d_quadcurv
= 0.0;
1533 #ifdef OSG_USE_NURBS_PATCH
1534 pcl_surface
->getParameterInterval_U(cl_min
[0], cl_add
[0]);
1535 pcl_surface
->getParameterInterval_V(cl_min
[1], cl_add
[1]);
1537 #ifdef OSG_ARBITRARY_SPLIT
1542 if(m_sbNormalApproximation
)
1544 //#ifndef OSG_USE_NURBS_PATCH
1547 du
[0] = crvvcl_cps
[1][0][0];
1548 du
[1] = crvvcl_cps
[1][0][1];
1549 du
[2] = crvvcl_cps
[1][0][2];
1551 // we take the difference of two homogenious cps, but as the length of the cross product
1552 // is irrevelant (we're calculating normals) we ignore the weights.
1553 // In addition the weight of cp[1][0] might be zero so we avoid dividing by it (multiply is OK).
1554 du
-= ccl_b00
* crvvcl_cps
[1][0][3];
1556 dv
[0] = crvvcl_cps
[0][1][0];
1557 dv
[1] = crvvcl_cps
[0][1][1];
1558 dv
[2] = crvvcl_cps
[0][1][2];
1559 dv
-= ccl_b00
* crvvcl_cps
[0][1][3];
1560 cl_nb00
= du
.cross(dv
);
1562 du
[0] = crvvcl_cps
[1][cui_n
][0];
1563 du
[1] = crvvcl_cps
[1][cui_n
][1];
1564 du
[2] = crvvcl_cps
[1][cui_n
][2];
1565 du
-= ccl_b0n
* crvvcl_cps
[1][cui_n
][3];
1566 dv
[0] = crvvcl_cps
[0][cui_n
- 1][0];
1567 dv
[1] = crvvcl_cps
[0][cui_n
- 1][1];
1568 dv
[2] = crvvcl_cps
[0][cui_n
- 1][2];
1569 dv
-= ccl_b0n
* crvvcl_cps
[0][cui_n
- 1][3];
1570 cl_nb0n
= du
.cross(-dv
);
1572 du
[0] = crvvcl_cps
[cui_m
- 1][0][0];
1573 du
[1] = crvvcl_cps
[cui_m
- 1][0][1];
1574 du
[2] = crvvcl_cps
[cui_m
- 1][0][2];
1575 du
-= ccl_bm0
* crvvcl_cps
[cui_m
- 1][0][3];
1576 dv
[0] = crvvcl_cps
[cui_m
][1][0];
1577 dv
[1] = crvvcl_cps
[cui_m
][1][1];
1578 dv
[2] = crvvcl_cps
[cui_m
][1][2];
1579 dv
-= ccl_bm0
* crvvcl_cps
[cui_m
][1][3];
1580 cl_nbm0
= -du
.cross(dv
);
1582 du
[0] = crvvcl_cps
[cui_m
- 1][cui_n
][0];
1583 du
[1] = crvvcl_cps
[cui_m
- 1][cui_n
][1];
1584 du
[2] = crvvcl_cps
[cui_m
- 1][cui_n
][2];
1585 du
-= ccl_bmn
* crvvcl_cps
[cui_m
- 1][cui_n
][3];
1586 dv
[0] = crvvcl_cps
[cui_m
][cui_n
- 1][0];
1587 dv
[1] = crvvcl_cps
[cui_m
][cui_n
- 1][1];
1588 dv
[2] = crvvcl_cps
[cui_m
][cui_n
- 1][2];
1589 dv
-= ccl_bmn
* crvvcl_cps
[cui_m
][cui_n
- 1][3];
1590 cl_nbmn
= du
.cross(dv
); // -du X -dv => du X dv
1593 cl_nb00 = ( crvvcl_cps[ 1 ][ 0 ] - crvvcl_cps[ 0 ][ 0 ] ).cross(
1594 ( crvvcl_cps[ 0 ][ 1 ] - crvvcl_cps[ 0 ][ 0 ] ) );
1595 cl_nb0n = ( crvvcl_cps[ 1 ][ cui_n ] - crvvcl_cps[ 0 ][ cui_n ] ).cross(
1596 ( crvvcl_cps[ 0 ][ cui_n ] - crvvcl_cps[ 0 ][ cui_n - 1 ] ) );
1597 cl_nbm0 = ( crvvcl_cps[ cui_m ][ 1 ] - crvvcl_cps[ cui_m ][ 0 ] ).cross(
1598 ( crvvcl_cps[ cui_m - 1 ][ 0 ] - crvvcl_cps[ cui_m ][ 0 ] ) );
1599 cl_nbmn = ( crvvcl_cps[ cui_m ][ cui_n ] - crvvcl_cps[ cui_m - 1 ][ cui_n ] ).cross(
1600 ( crvvcl_cps[ cui_m ][ cui_n ] - crvvcl_cps[ cui_m ][ cui_n - 1 ] ) );
1602 // std::cerr << cl_nb00 << std::endl;
1603 // std::cerr << cl_nb0n << std::endl;
1604 // std::cerr << cl_nbm0 << std::endl;
1605 // std::cerr << cl_nbmn << std::endl << std::endl;
1608 cl_normal = pcl_surface->computeNormal( cl_uv, i_err, cl_position );
1609 cl_nb00[0] = cl_normal[ 0 ];
1610 cl_nb00[1] = cl_normal[ 1 ];
1611 cl_nb00[2] = cl_normal[ 2 ];
1613 cl_uv[1] += cl_add[1];
1614 cl_normal = pcl_surface->computeNormal( cl_uv, i_err, cl_position );
1615 cl_nb0n[0] = cl_normal[ 0 ];
1616 cl_nb0n[1] = cl_normal[ 1 ];
1617 cl_nb0n[2] = cl_normal[ 2 ];
1619 cl_uv[0] += cl_add[0];
1620 cl_normal = pcl_surface->computeNormal( cl_uv, i_err, cl_position );
1621 cl_nbmn[0] = cl_normal[ 0 ];
1622 cl_nbmn[1] = cl_normal[ 1 ];
1623 cl_nbmn[2] = cl_normal[ 2 ];
1625 cl_uv[1] = cl_min[1];
1626 cl_normal = pcl_surface->computeNormal( cl_uv, i_err, cl_position );
1627 cl_nbm0[0] = cl_normal[ 0 ];
1628 cl_nbm0[1] = cl_normal[ 1 ];
1629 cl_nbm0[2] = cl_normal[ 2 ];
1630 // std::cerr << cl_nb00 << std::endl;
1631 // std::cerr << cl_nb0n << std::endl;
1632 // std::cerr << cl_nbm0 << std::endl;
1633 // std::cerr << cl_nbmn << std::endl << std::endl;
1636 d_quad_size
= cl_nb00
.squareLength();
1637 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
1639 cl_nb00
*= 1.0 / sqrt(d_quad_size
);
1641 d_quad_size
= cl_nb0n
.squareLength();
1642 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
1644 cl_nb0n
*= 1.0 / sqrt(d_quad_size
);
1646 d_quad_size
= cl_nbm0
.squareLength();
1647 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
1649 cl_nbm0
*= 1.0 / sqrt(d_quad_size
);
1651 d_quad_size
= cl_nbmn
.squareLength();
1652 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
1654 cl_nbmn
*= 1.0 / sqrt(d_quad_size
);
1656 // AKOS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1657 // std::cerr << cl_nb00 << std::endl;
1658 // std::cerr << cl_nb0n << std::endl;
1659 // std::cerr << cl_nbm0 << std::endl;
1660 // std::cerr << cl_nbmn << std::endl << std::endl;
1662 #ifndef OSG_USE_NURBS_PATCH
1663 cl_ndcx0
= (cl_nbm0
- cl_nb00
) * cd_rm
;
1664 cl_ndcxn
= (cl_nbmn
- cl_nb0n
) * cd_rm
;
1665 cl_ndc0x
= (cl_nb0n
- cl_nb00
) * cd_rn
;
1666 cl_ndcmx
= (cl_nbmn
- cl_nbm0
) * cd_rn
;
1669 if( (cl_nb00
.squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1670 (cl_nb0n
.squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1671 (cl_nbm0
.squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1672 (cl_nbmn
.squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1673 ((ccl_b00
- ccl_b0n
).squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1674 ((ccl_b0n
- ccl_bmn
).squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1675 ((ccl_bmn
- ccl_bm0
).squareLength() < DCTP_EPS
* DCTP_EPS
) ||
1676 ((ccl_bm0
- ccl_b00
).squareLength() < DCTP_EPS
* DCTP_EPS
))
1682 d_quadcurv
= osgMax(osgMax( (cl_nb00
- cl_nb0n
).squareLength() / (ccl_b00
- ccl_b0n
).squareLength(),
1683 (cl_nb0n
- cl_nbmn
).squareLength() / (ccl_b0n
- ccl_bmn
).squareLength() ),
1684 osgMax( (cl_nbmn
- cl_nbm0
).squareLength() / (ccl_bmn
- ccl_bm0
).squareLength(),
1685 (cl_nbm0
- cl_nb00
).squareLength() / (ccl_bm0
- ccl_b00
).squareLength() ) );
1687 // d_quadcurv *= 4.0; // 0.5 pixel geometric, 1 pixel shading error
1690 if(d_quadcurv
< 1e-4)
1692 // std::cerr << d_quadcurv << std::endl;
1697 std::cerr << d_quadcurv << std::endl;
1701 #ifndef OSG_USE_NURBS_PATCH
1704 if(m_sbNormalApproximation
)
1711 for(ui_i
= 0; ui_i
<= cui_m
; ++ui_i
)
1713 #ifdef OSG_USE_NURBS_PATCH
1714 // cl_uv[0] += ( crvd_knot_u[ cui_dim_u + ui_i ] - crvd_knot_u[ ui_i ] ) / cui_dim_u;
1717 for(ui_idx
= 0; ui_idx
< cui_dim_u
; ++ui_idx
)
1719 cl_uv
[0] += crvd_knot_u
[ui_idx
+ ui_i
+ 1];
1722 cl_uv
[0] /= cui_dim_u
;
1724 const double cd_xrel
= (cl_uv
[0] - cl_min
[0]) / cl_add
[0];
1726 cl_ci0
= (ccl_bm0
- ccl_b00
) * cd_xrel
+ ccl_b00
;
1727 cl_cin
= (ccl_bmn
- ccl_b0n
) * cd_xrel
+ ccl_b0n
;
1728 if(m_sbNormalApproximation
)
1730 cl_nci0
= (cl_nbm0
- cl_nb00
) * cd_xrel
+ cl_nb00
;
1731 cl_ncin
= (cl_nbmn
- cl_nb0n
) * cd_xrel
+ cl_nb0n
;
1738 const Vec3d ccl_dcix
= (cl_cin
- cl_ci0
) * cd_rn
;
1740 if(m_sbNormalApproximation
)
1746 cl_ndcix
= (cl_ncin
- cl_nci0
) * cd_rn
;
1749 cl_uv
[0] = ui_i
* cd_rm
;
1752 for(ui_j
= 0; ui_j
<= cui_n
; ++ui_j
)
1754 #ifdef OSG_USE_NURBS_PATCH
1757 for(ui_idx
= 0; ui_idx
< cui_dim_v
; ++ui_idx
)
1759 cl_uv
[1] += crvd_knot_v
[ui_idx
+ ui_j
+ 1];
1762 cl_uv
[1] /= cui_dim_v
;
1764 const double cd_yrel
= (cl_uv
[1] - cl_min
[1]) / cl_add
[1];
1766 cl_cij
= cl_ci0
+ (cl_cin
- cl_ci0
) * cd_yrel
;
1767 if(m_sbNormalApproximation
)
1769 cl_ncij
= cl_nci0
+ (cl_ncin
- cl_nci0
) * cd_yrel
;
1772 const Vec3d ccl_dcxj
= cl_cmj
- cl_c0j
;
1774 if(m_sbNormalApproximation
)
1776 cl_ndcxj
= cl_ncmj
- cl_nc0j
;
1779 cl_uv
[1] = ui_j
* cd_rn
;
1781 #ifdef OSG_DIFF_TO_BILIN
1782 #ifdef OSG_USE_NURBS_PATCH
1783 #ifdef OSG_CONSERVATIVE_ERROR
1784 cl_bij
= crvvcl_cps
[ui_i
][ui_j
];
1786 if(m_sbNormalApproximation
)
1788 // TODO Vec3f f�r normale, Pnt3f f�r punkt
1789 cl_nbij
= pcl_surface
->computeNormal(cl_uv
, i_err
, cl_bij
);
1790 d_quad_size
= cl_ncij
.squareLength();
1791 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
1793 cl_norm
= cl_ncij
* (1.0 / sqrt(d_quad_size
) );
1799 // std::cerr << cl_uv << cl_nbij << cl_norm << std::endl;
1804 cl_bij
= pcl_surface
->compute(cl_uv
, i_err
);
1808 #ifdef OSG_CONSERVATIVE_ERROR
1809 cl_bij
= crvvcl_cps
[ui_i
][ui_j
];
1811 cl_bij
= pcl_surface
->computewdeCasteljau(cl_uv
, i_err
);
1814 if( (m_sbNormalApproximation
) && (cl_nbij
.squareLength() > DCTP_EPS
* DCTP_EPS
) )
1816 // calculate shading error
1817 d_quad_size
= cl_nbij
.squareLength() / d_quadcurv
;
1819 #ifdef OSG_EUCLID_ERRORS
1820 // for euclidian norm first calculate distance to next correcly shaded pixel
1821 d_quad_size
+= (cl_bij
- cl_cij
).squareLength();
1824 // the corner points are correcly shaded pixels...
1825 d_quad_size
= osgMin(d_quad_size
, (cl_bij
- ccl_b00
).squareLength() );
1826 d_quad_size
= osgMin(d_quad_size
, (cl_bij
- ccl_b0n
).squareLength() );
1827 d_quad_size
= osgMin(d_quad_size
, (cl_bij
- ccl_bm0
).squareLength() );
1828 d_quad_size
= osgMin(d_quad_size
, (cl_bij
- ccl_bmn
).squareLength() );
1830 #ifdef OSG_EUCLID_ERRORS
1831 d_quad_size
= sqrt(d_quad_size
);
1833 // for maximum norm choose the maximum error
1834 d_quad_size
= sqrt(osgMax( (cl_bij
- cl_cij
).squareLength(), d_quad_size
) );
1839 d_quad_size
= sqrt( (cl_bij
- cl_cij
).squareLength() );
1841 #ifdef OSG_ARBITRARY_SPLIT
1842 if(osgAbs(d_quad_size
- ptCell
->ptErrorCell
->fError
) < DCTP_EPS
)
1844 double cd_old_x
= osgMin(cl_worst
[0] - cl_min
[0], cl_min
[0] + cl_add
[0] - cl_worst
[0]);
1845 double cd_old_y
= osgMin(cl_worst
[1] - cl_min
[1], cl_min
[1] + cl_add
[1] - cl_worst
[1]);
1846 double cd_new_x
= osgMin(cl_uv
[0] - cl_min
[0], cl_min
[0] + cl_add
[0] - cl_uv
[0]);
1847 double cd_new_y
= osgMin(cl_uv
[1] - cl_min
[1], cl_min
[1] + cl_add
[1] - cl_uv
[1]);
1848 // std::cerr << cd_old_x * cd_old_x + cd_old_y * cd_old_y << " " << cd_new_x * cd_new_x + cd_new_y * cd_new_y << std::endl;
1849 if(cd_old_x
* cd_old_x
+ cd_old_y
* cd_old_y
<= cd_new_x
* cd_new_x
+ cd_new_y
* cd_new_y
)
1853 if(d_quad_size
> ptCell
->ptErrorCell
->fError
)
1855 ptCell
->ptErrorCell
->fError
= float(d_quad_size
);
1860 if(d_quad_size
> ptCell
->ptErrorCell
->fError
)
1862 ptCell
->ptErrorCell
->fError
= float(d_quad_size
);
1863 #ifdef OSG_ARBITRARY_SPLIT
1868 #ifdef OSG_CONSERVATIVE_ERROR
1869 cl_bij
= crvvcl_cps
[ui_i
][ui_j
];
1871 #ifdef OSG_USE_NURBS_PATCH
1872 cl_bij
= pcl_surface
->compute(cl_uv
, i_err
);
1874 cl_bij
= pcl_surface
->computewdeCasteljau(cl_uv
, i_err
);
1877 d_quad_size
= osgMin(computeDistToTriangle(cl_bij
, ccl_b00
, ccl_b0n
, ccl_bm0
),
1878 computeDistToTriangle(cl_bij
, ccl_bmn
, ccl_b0n
, ccl_bm0
) );
1879 // std::cerr << d_quad_size << std::endl;
1880 if(d_quad_size
> ptCell
->ptErrorCell
->fError
)
1882 // std::cerr << d_quad_size << std::endl;
1883 ptCell
->ptErrorCell
->fError
= ( float ) d_quad_size
;
1885 d_quad_size
= osgMin(computeDistToTriangle(cl_bij
, ccl_b0n
, ccl_b00
, ccl_bmn
),
1886 computeDistToTriangle(cl_bij
, ccl_bm0
, ccl_b00
, ccl_bmn
) );
1887 // std::cerr << d_quad_size << std::endl;
1888 if(d_quad_size
> ptCell
->ptErrorCell
->fError
)
1890 // std::cerr << d_quad_size << std::endl;
1891 ptCell
->ptErrorCell
->fError
= ( float ) d_quad_size
;
1894 #ifndef OSG_USE_NURBS_PATCH
1901 #ifndef OSG_USE_NURBS_PATCH
1907 // add twist vector error
1908 #ifdef OSG_DIFF_TO_BILIN
1909 #ifdef OSG_CONSERVATIVE_ERROR
1910 ptCell
->ptErrorCell
->fError
+= ( float ) sqrt( (ccl_b00
- ccl_b0n
+ ccl_bmn
- ccl_bm0
).squareLength() ) * 0.25;
1913 // ptCell->ptErrorCell->fError *= 0.1;
1914 // std::cerr << ptCell->ptErrorCell->fError << std::endl;
1915 #ifdef OSG_USE_KD_TREE
1916 #ifdef OSG_ARBITRARY_SPLIT
1917 // std::cerr << cl_min << cl_add << cl_worst << std::endl;
1918 if( (osgAbs(cl_worst
[0] - cl_min
[0]) <= osgMax(DCTP_EPS
, 1e-4 * cl_add
[0]) ) ||
1919 (osgAbs(cl_worst
[0] - (cl_min
[0] + cl_add
[0]) ) <= osgMax(DCTP_EPS
, 1e-4 * cl_add
[0]) ) )
1921 // std::cerr << "y";
1922 if( (osgAbs(cl_worst
[1] - cl_min
[1]) <= osgMax(DCTP_EPS
, 1e-4 * cl_add
[1]) ) ||
1923 (osgAbs(cl_worst
[1] - (cl_min
[1] + cl_add
[1]) ) <= osgMax(DCTP_EPS
, 1e-4 * cl_add
[1]) ) )
1925 if(osgAbs(cl_add
[0]) < osgAbs(cl_add
[1]) )
1927 // std::cerr << "my";
1928 ptCell
->ptErrorCell
->fSplitValue
= 0.5;
1932 // std::cerr << "mx";
1933 ptCell
->ptErrorCell
->fSplitValue
= -0.5;
1938 ptCell
->ptErrorCell
->fSplitValue
= (cl_worst
[1] - cl_min
[1]) / cl_add
[1];
1941 else if( (osgAbs(cl_worst
[1] - cl_min
[1]) <= osgMax(DCTP_EPS
, 1e-4 * cl_add
[1]) ) ||
1942 (osgAbs(cl_worst
[1] - (cl_min
[1] + cl_add
[1]) ) <= osgMax(DCTP_EPS
, 1e-4 * cl_add
[1]) ) )
1944 // std::cerr << "x";
1945 ptCell
->ptErrorCell
->fSplitValue
= -(cl_worst
[0] - cl_min
[0]) / cl_add
[0];
1952 cl_uv
[0] = cl_worst
[0];
1953 cl_uv
[1] = cl_min
[1];
1954 if(m_sbNormalApproximation
)
1956 cl_nci0
= pcl_surface
->computeNormal(cl_uv
, i_err
, cl_ci0
);
1957 cl_uv
[1] += cl_add
[1];
1958 cl_ncin
= pcl_surface
->computeNormal(cl_uv
, i_err
, cl_cin
);
1959 cl_uv
[1] = cl_worst
[1];
1960 cl_ncij
= pcl_surface
->computeNormal(cl_uv
, i_err
, cl_cij
);
1962 cl_bij
= cl_ci0
+ (cl_cin
- cl_ci0
) * ( (cl_worst
[1] - cl_min
[1]) / cl_add
[1]);
1963 cl_nbij
= cl_nci0
+ (cl_ncin
- cl_nci0
) * ( (cl_worst
[1] - cl_min
[1]) / cl_add
[1]);
1964 d_quad_size
= cl_nbij
.squareLength();
1965 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
1967 cl_nbij
*= 1.0 / sqrt(d_quad_size
);
1972 cl_ci0
= pcl_surface
->compute(cl_uv
, i_err
);
1973 cl_uv
[1] += cl_add
[1];
1974 cl_cin
= pcl_surface
->compute(cl_uv
, i_err
);
1975 cl_uv
[1] = cl_worst
[1];
1976 cl_cij
= pcl_surface
->compute(cl_uv
, i_err
);
1978 cl_bij
= cl_ci0
+ (cl_cin
- cl_ci0
) * ( (cl_worst
[1] - cl_min
[1]) / cl_add
[1]);
1981 // const double cd_hdiff = computeDistToLine( cl_cij, cl_ci0, cl_cin );
1982 // const double cd_hdiff = sqrt( ( cl_cij - cl_bij ).squareLength( ) );
1983 if( (m_sbNormalApproximation
) && (cl_ncij
.squareLength() > DCTP_EPS
* DCTP_EPS
) )
1985 // calculate shading error
1986 d_hdiff
= (cl_ncij
- cl_nbij
).squareLength() / d_quadcurv
;
1988 #ifdef OSG_EUCLID_ERRORS
1989 // for euclidian norm first calculate distance to next correcly shaded pixel
1990 d_hdiff
+= (cl_cij
- cl_bij
).squareLength();
1993 // the new corner points will be correcly shaded pixels...
1994 // d_hdiff = osgMin( d_hdiff, ( cl_cij - cl_ci0 ).squareLength( ) );
1995 // d_hdiff = osgMin( d_hdiff, ( cl_cij - cl_cin ).squareLength( ) );
1997 #ifdef OSG_EUCLID_ERRORS
1998 d_hdiff
= sqrt(d_hdiff
);
2000 // for maximum norm choose the maximum error
2001 d_hdiff
= sqrt(osgMax( (cl_cij
- cl_bij
).squareLength(), d_hdiff
) );
2004 /* #ifdef OSG_EUCLID_ERRORS
2005 d_hdiff = sqrt( ( cl_cij - cl_bij ).squareLength( )
2006 + ( cl_ncij - cl_nbij ).squareLength( ) / d_quadcurv );
2008 d_hdiff = sqrt( osgMax( ( cl_cij - cl_bij ).squareLength( ),
2009 ( cl_ncij - cl_nbij ).squareLength( ) / d_quadcurv ) );
2011 d_hdiff
+= sqrt( (cl_ci0
- cl_cin
).squareLength() ) * 0.0001;
2015 d_hdiff
= sqrt( (cl_cij
- cl_bij
).squareLength() )
2016 + sqrt( (cl_ci0
- cl_cin
).squareLength() ) * 0.0001;
2018 // const double cd_hdiff = sqrt( ( cl_ci0 - cl_cin ).squareLength( ) );
2022 /* std::cerr.precision( 4 );
2023 if( m_sbNormalApproximation )
2025 std::cerr << cl_ci0 << cl_cij << cl_cin << cl_nci0 << cl_ncij << cl_ncin << d_hdiff << std::endl;
2029 std::cerr << cl_ci0 << cl_cij << cl_cin << d_hdiff << std::endl;
2032 if(m_sbNormalApproximation
)
2034 cl_uv
[0] = cl_min
[0];
2035 cl_nci0
= pcl_surface
->computeNormal(cl_uv
, i_err
, cl_ci0
);
2036 cl_uv
[0] += cl_add
[0];
2037 cl_ncin
= pcl_surface
->computeNormal(cl_uv
, i_err
, cl_cin
);
2039 cl_bij
= cl_ci0
+ (cl_cin
- cl_ci0
) * ( (cl_worst
[0] - cl_min
[0]) / cl_add
[0]);
2040 cl_nbij
= cl_nci0
+ (cl_ncin
- cl_nci0
) * ( (cl_worst
[0] - cl_min
[0]) / cl_add
[0]);
2041 d_quad_size
= cl_nbij
.squareLength();
2042 if(d_quad_size
> DCTP_EPS
* DCTP_EPS
)
2044 cl_nbij
*= 1.0 / sqrt(d_quad_size
);
2049 cl_uv
[0] = cl_min
[0];
2050 cl_ci0
= pcl_surface
->compute(cl_uv
, i_err
);
2051 cl_uv
[0] += cl_add
[0];
2052 cl_cin
= pcl_surface
->compute(cl_uv
, i_err
);
2054 cl_bij
= cl_ci0
+ (cl_cin
- cl_ci0
) * ( (cl_worst
[0] - cl_min
[0]) / cl_add
[0]);
2057 // const double cd_vdiff = computeDistToLine( cl_cij, cl_ci0, cl_cin );
2058 // const double cd_vdiff = sqrt( ( cl_cij - cl_bij ).squareLength( ) );
2059 if( (m_sbNormalApproximation
) && (cl_ncij
.squareLength() > DCTP_EPS
* DCTP_EPS
) )
2061 // calculate shading error
2062 d_vdiff
= (cl_ncij
- cl_nbij
).squareLength() / d_quadcurv
;
2064 #ifdef OSG_EUCLID_ERRORS
2065 // for euclidian norm first calculate distance to next correcly shaded pixel
2066 d_vdiff
+= (cl_cij
- cl_bij
).squareLength();
2069 // the new corner points will be correcly shaded pixels...
2070 // d_vdiff = osgMin( d_vdiff, ( cl_cij - cl_ci0 ).squareLength( ) );
2071 // d_vdiff = osgMin( d_vdiff, ( cl_cij - cl_cin ).squareLength( ) );
2073 #ifdef OSG_EUCLID_ERRORS
2074 d_vdiff
= sqrt(d_vdiff
);
2076 // for maximum norm choose the maximum error
2077 d_vdiff
= sqrt(osgMax( (cl_cij
- cl_bij
).squareLength(), d_vdiff
) );
2080 /* #ifdef OSG_EUCLID_ERRORS
2081 d_vdiff = sqrt( ( cl_cij - cl_bij ).squareLength( )
2082 + ( cl_ncij - cl_nbij ).squareLength( ) / d_quadcurv );
2084 d_vdiff = sqrt( osgMax( ( cl_cij - cl_bij ).squareLength( ),
2085 ( cl_ncij - cl_nbij ).squareLength( ) / d_quadcurv ) );
2087 d_vdiff
+= sqrt( (cl_ci0
- cl_cin
).squareLength() ) * 0.0001;
2091 d_vdiff
= sqrt( (cl_cij
- cl_bij
).squareLength() )
2092 + sqrt( (cl_ci0
- cl_cin
).squareLength() ) * 0.0001;
2094 // const double cd_vdiff = sqrt( ( cl_ci0 - cl_cin ).squareLength( ) );
2096 /* if( m_sbNormalApproximation )
2098 std::cerr << cl_ci0 << cl_cij << cl_cin << cl_nci0 << cl_ncij << cl_ncin << d_vdiff << std::endl;
2102 std::cerr << cl_ci0 << cl_cij << cl_cin << d_vdiff << std::endl;
2104 // std::cerr << cd_hdiff << " " << cd_vdiff << std::endl;
2105 // std::cerr << "--------------------" << std::endl;
2107 if(d_hdiff
< d_vdiff
)
2109 ptCell
->ptErrorCell
->fSplitValue
= -(cl_worst
[0] - cl_min
[0]) / cl_add
[0];
2113 ptCell
->ptErrorCell
->fSplitValue
= (cl_worst
[1] - cl_min
[1]) / cl_add
[1];
2116 // std::cerr << cl_min << cl_min + cl_add << std::endl;
2117 // std::cerr << ptCell->ptErrorCell->fSplitValue << std::endl;
2119 cl_uv
[0] = cl_min
[0] + cl_add
[0] * 0.5;
2120 cl_uv
[1] = cl_min
[1];
2121 cl_ci0
= pcl_surface
->compute(cl_uv
, i_err
);
2122 cl_uv
[1] += cl_add
[1];
2123 cl_cin
= pcl_surface
->compute(cl_uv
, i_err
);
2124 cl_uv
[1] -= cl_add
[1] * 0.5;
2125 cl_cij
= pcl_surface
->compute(cl_uv
, i_err
);
2127 // const double cd_hdiff = computeDistToLine( cl_cij, cl_ci0, cl_cin );
2128 // const double cd_hdiff = sqrt( ( cl_cij - ( cl_ci0 + cl_cin ) * 0.5 ).squareLength( ) );
2129 // const double cd_hdiff = sqrt( ( cl_cij - cl_ci0 ).squareLength( ) ) + sqrt( ( cl_cij - cl_cin ).squareLength( ) );
2130 const double cd_hdiff
= computeDistToLine(cl_cij
, cl_ci0
, cl_cin
)
2131 + sqrt( (cl_ci0
- cl_cin
).squareLength() ) * 0.001;
2133 // std::cerr.precision( 4 );
2134 // std::cerr << cl_ci0 << cl_cij << cl_cin << cd_hdiff << std::endl;
2136 cl_uv
[0] = cl_min
[0];
2137 cl_ci0
= pcl_surface
->compute(cl_uv
, i_err
);
2138 cl_uv
[0] += cl_add
[0];
2139 cl_cin
= pcl_surface
->compute(cl_uv
, i_err
);
2141 // const double cd_vdiff = computeDistToLine( cl_cij, cl_ci0, cl_cin );
2142 // const double cd_vdiff = sqrt( ( cl_cij - ( cl_ci0 + cl_cin ) * 0.5 ).squareLength( ) );
2143 // const double cd_vdiff = sqrt( ( cl_cij - cl_ci0 ).squareLength( ) ) + sqrt( ( cl_cij - cl_cin ).squareLength( ) );
2144 const double cd_vdiff
= computeDistToLine(cl_cij
, cl_ci0
, cl_cin
)
2145 + sqrt( (cl_ci0
- cl_cin
).squareLength() ) * 0.001;
2147 // std::cerr << cl_ci0 << cl_cij << cl_cin << cd_vdiff << std::endl;
2148 // std::cerr << cd_hdiff << " " << cd_vdiff << std::endl;
2149 // std::cerr << "--------------------" << std::endl;
2151 ptCell
->ptErrorCell
->bSplitHoriz
= (cd_hdiff
< cd_vdiff
);
2155 /* const double cd_size = 0.5 * sqrt( osgMax( osgMax( osgMax( ( ccl_b00 - ccl_b0n ).squareLength( ),
2156 ( ccl_b0n - ccl_bmn ).squareLength( ) ),
2157 osgMax( ( ccl_bmn - ccl_bm0 ).squareLength( ),
2158 ( ccl_bm0 - ccl_b00 ).squareLength( ) ) ),
2159 osgMax( ( ccl_b00 - ccl_bmn ).squareLength( ),
2160 ( ccl_b0n - ccl_bm0 ).squareLength( ) ) ) );
2162 if( ( cd_size > DCTP_EPS ) &&
2163 ( ptCell->ptErrorCell->fError > cd_size ) )
2165 // error can't be larger than the current face, except for a torus. ;-)
2166 ptCell->ptErrorCell->fError = cd_size;
2171 #ifndef OSG_USE_NURBS_PATCH
2172 void CErrorQuadTree::ComputeBPTree(std::vector
<std::vector
<BezierTensorSurface
> > *pvvclPatches
,
2173 const std::vector
<double> * cpvdIntervalsU
,
2174 const std::vector
<double> * cpvdIntervalsV
)
2176 m_ptBPRoot
= new SBPETreeCell
;
2177 m_ptBPRoot
->uiBottom
= 0;
2178 m_ptBPRoot
->uiTop
= (*cpvdIntervalsV
).size() - 2;
2179 m_ptBPRoot
->uiLeft
= 0;
2180 m_ptBPRoot
->uiRight
= (*cpvdIntervalsU
).size() - 2;
2181 m_ptBPRoot
->fPrevError
= 1e+32;
2182 ComputeBPError(m_ptBPRoot
, pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2183 SubdivideBPTree(m_ptBPRoot
, pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2187 void CErrorQuadTree::ComputeBPError(SBPETreeCell
* pclBPNode
,
2188 std::vector
<std::vector
<BezierTensorSurface
> > *pvvclPatches
,
2189 const std::vector
<double> * cpvdIntervalsU
,
2190 const std::vector
<double> * cpvdIntervalsV
)
2192 unsigned int ui_u_surf
;
2193 unsigned int ui_v_surf
;
2194 BezierTensorSurface
*pcl_surface
;
2209 // std::cerr << pclBPNode->uiLeft << " - " << pclBPNode->uiRight << std::endl;
2210 // std::cerr << pclBPNode->uiBottom << " - " << pclBPNode->uiTop << std::endl;
2212 // std::cerr << ( *cpvdIntervalsU ).size( ) << " x " << ( *cpvdIntervalsV ).size( ) << std::endl;
2214 pclBPNode
->fError
= 0.0;
2216 /* if( ( pclBPNode->uiLeft == pclBPNode->uiRight ) &&
2217 ( pclBPNode->uiBottom == pclBPNode->uiTop ) )
2219 return; // handled as single bezier patch
2222 pcl_surface
= &( (*pvvclPatches
)[pclBPNode
->uiLeft
][pclBPNode
->uiBottom
]);
2223 const Vec3d ccl_a00
= pcl_surface
->getControlPointMatrix()[0][0];
2225 pcl_surface
= &( (*pvvclPatches
)[pclBPNode
->uiRight
][pclBPNode
->uiBottom
]);
2226 const Vec3d ccl_s0n
= pcl_surface
->getControlPointMatrix()[0][pcl_surface
->getControlPointMatrix()[0].size() - 1];
2227 const Vec3d ccl_a0n
= ccl_s0n
- ccl_a00
;
2229 pcl_surface
= &( (*pvvclPatches
)[pclBPNode
->uiLeft
][pclBPNode
->uiTop
]);
2230 const Vec3d ccl_sm0
= pcl_surface
->getControlPointMatrix()[pcl_surface
->getControlPointMatrix().size() - 1][0];
2231 const Vec3d ccl_am0
= ccl_sm0
- ccl_a00
;
2233 pcl_surface
= &( (*pvvclPatches
)[pclBPNode
->uiRight
][pclBPNode
->uiTop
]);
2234 const Vec3d ccl_smn
= pcl_surface
->getControlPointMatrix()[pcl_surface
->getControlPointMatrix().size() - 1][pcl_surface
->getControlPointMatrix()[0].size() - 1];
2235 const Vec3d ccl_amn
= ccl_smn
- ccl_am0
- ccl_a00
;
2237 for(ui_v_surf
= pclBPNode
->uiBottom
; ui_v_surf
<= pclBPNode
->uiTop
; ++ui_v_surf
)
2239 // std::cerr << "v:" << ui_v_surf << std::endl;
2240 const double cd_mul_v
= ( (*cpvdIntervalsV
)[ui_v_surf
] - (*cpvdIntervalsV
)[pclBPNode
->uiBottom
]) / ( (*cpvdIntervalsV
)[pclBPNode
->uiTop
+ 1] - (*cpvdIntervalsV
)[pclBPNode
->uiBottom
]);
2241 const double cd_mul_vn
= ( (*cpvdIntervalsV
)[ui_v_surf
+ 1] - (*cpvdIntervalsV
)[pclBPNode
->uiBottom
]) / ( (*cpvdIntervalsV
)[pclBPNode
->uiTop
+ 1] - (*cpvdIntervalsV
)[pclBPNode
->uiBottom
]);
2243 for(ui_u_surf
= pclBPNode
->uiLeft
; ui_u_surf
<= pclBPNode
->uiRight
; ++ui_u_surf
)
2245 // std::cerr << "u:" << ui_u_surf << std::endl;
2246 pcl_surface
= &( (*pvvclPatches
)[ui_u_surf
][ui_v_surf
]);
2248 const std::vector
<std::vector
<Vec3d
> > &crvvcl_cps
= pcl_surface
->getControlPointMatrix();
2249 const unsigned int cui_m
= crvvcl_cps
.size() - 1;
2250 const unsigned int cui_n
= crvvcl_cps
[0].size() - 1;
2251 const double cd_mul_u
= ( (*cpvdIntervalsU
)[ui_u_surf
] - (*cpvdIntervalsU
)[pclBPNode
->uiLeft
]) / ( (*cpvdIntervalsU
)[pclBPNode
->uiRight
+ 1] - (*cpvdIntervalsU
)[pclBPNode
->uiLeft
]);
2252 const double cd_mul_un
= ( (*cpvdIntervalsU
)[ui_u_surf
+ 1] - (*cpvdIntervalsU
)[pclBPNode
->uiLeft
]) / ( (*cpvdIntervalsU
)[pclBPNode
->uiRight
+ 1] - (*cpvdIntervalsU
)[pclBPNode
->uiLeft
]);
2253 const Vec3d ccl_b00
= ccl_a00
+ ccl_a0n
* cd_mul_v
+ (ccl_am0
+ ccl_amn
* cd_mul_v
) * cd_mul_u
;
2254 const Vec3d ccl_b0n
= ccl_a00
+ ccl_a0n
* cd_mul_vn
+ (ccl_am0
+ ccl_amn
* cd_mul_vn
) * cd_mul_u
;
2255 const Vec3d ccl_bm0
= ccl_a00
+ ccl_a0n
* cd_mul_v
+ (ccl_am0
+ ccl_amn
* cd_mul_v
) * cd_mul_un
;
2256 const Vec3d ccl_bmn
= ccl_a00
+ ccl_a0n
* cd_mul_vn
+ (ccl_am0
+ ccl_amn
* cd_mul_vn
) * cd_mul_un
;
2257 const double cd_rn
= 1.0 / cui_n
;
2258 const double cd_rm
= 1.0 / cui_m
;
2259 const Vec3d ccl_dcx0
= (ccl_bm0
- ccl_b00
) * cd_rm
;
2260 const Vec3d ccl_dcxn
= (ccl_bmn
- ccl_b0n
) * cd_rm
;
2261 const Vec3d ccl_dc0x
= (ccl_b0n
- ccl_b00
) * cd_rn
;
2262 const Vec3d ccl_dcmx
= (ccl_bmn
- ccl_bm0
) * cd_rn
;
2264 // std::cerr << cui_n << "," << cui_m << std::endl;
2265 // std::cerr << ( void* ) pclBPNode << std::endl;
2270 for(ui_i
= 0; ui_i
<= cui_m
; ++ui_i
)
2276 const Vec3d ccl_dcix
= (cl_cin
- cl_ci0
) * cd_rn
;
2278 cl_uv
[0] = ui_i
* cd_rm
;
2280 for(ui_j
= 0; ui_j
<= cui_n
; ++ui_j
)
2282 const Vec3d ccl_dcxj
= cl_cmj
- cl_c0j
;
2284 cl_uv
[1] = ui_j
* cd_rn
;
2285 #ifdef OSG_DIFF_TO_BILIN
2286 // cl_bij = crvvcl_cps[ ui_i ][ ui_j ] - cl_cij;
2287 cl_bij
= pcl_surface
->computewdeCasteljau(cl_uv
, i_err
) - cl_cij
;
2288 // std::cerr << ccl_dcix << "x" << ccl_dcxj << std::endl;
2289 /* cl_norm = ccl_dcix.cross( ccl_dcxj );
2290 d_quad_size = cl_norm.squareLength( );
2291 if( d_quad_size > 0.0 )
2293 // std::cerr << "qs:" << d_quad_size << std::endl;
2294 cl_norm *= 1.0 / sqrt( d_quad_size );
2295 d_quad_size = osgAbs( cl_bij.dot( cl_norm ) );
2296 if( d_quad_size > pclBPNode->fError )
2298 pclBPNode->fError = ( float ) d_quad_size;
2303 d_quad_size
= sqrt(cl_bij
.squareLength() );
2304 // std::cerr << "qs:" << d_quad_size << std::endl;
2305 if(d_quad_size
> pclBPNode
->fError
)
2307 pclBPNode
->fError
= ( float ) d_quad_size
;
2311 // std::cerr << cl_uv << std::endl;
2312 cl_bij
= pcl_surface
->computewdeCasteljau(cl_uv
, i_err
);
2313 // std::cerr << i_err << std::endl;
2314 if(cl_uv
[0] + cl_uv
[1] <= 1.0)
2316 d_quad_size
= computeDistToTriangle(cl_bij
, ccl_a00
, ccl_s0n
, ccl_sm0
);
2320 d_quad_size
= computeDistToTriangle(cl_bij
, ccl_smn
, ccl_s0n
, ccl_sm0
);
2322 // d_quad_size = osgMin( computeDistToTriangle( cl_bij, ccl_a00, ccl_s0n, ccl_sm0 ),
2323 // computeDistToTriangle( cl_bij, ccl_smn, ccl_s0n, ccl_sm0 ) );
2324 if(d_quad_size
> pclBPNode
->fError
)
2326 pclBPNode
->fError
= ( float ) d_quad_size
;
2328 if(cl_uv
[0] <= cl_uv
[1])
2330 d_quad_size
= computeDistToTriangle(cl_bij
, ccl_s0n
, ccl_a00
, ccl_smn
);
2334 d_quad_size
= computeDistToTriangle(cl_bij
, ccl_sm0
, ccl_a00
, ccl_smn
);
2336 // d_quad_size = osgMin( computeDistToTriangle( cl_bij, ccl_s0n, ccl_a00, ccl_smn ),
2337 // computeDistToTriangle( cl_bij, ccl_sm0, ccl_a00, ccl_smn ) );
2338 if(d_quad_size
> pclBPNode
->fError
)
2340 pclBPNode
->fError
= ( float ) d_quad_size
;
2342 // std::cerr << ccl_a00 << ccl_a0n << ccl_am0 << ccl_amn << std::endl << std::endl;
2355 // add twist vector error
2356 #ifdef OSG_DIFF_TO_BILIN
2357 // pclBPNode->fError += ( float ) sqrt( ( ccl_amn - ccl_a0n ).squareLength( ) ) * 0.25;
2359 // pclBPNode->fError *= 0.1;
2360 // pcl_node->ptErrorCell->fError = 0.0;
2364 void CErrorQuadTree::SubdivideBPTree(SBPETreeCell
* pclBPNode
,
2365 std::vector
<std::vector
<BezierTensorSurface
> > *pvvclPatches
,
2366 const std::vector
<double> * cpvdIntervalsU
,
2367 const std::vector
<double> * cpvdIntervalsV
)
2369 unsigned int ui_diff
;
2372 while( (ui_diff
<= pclBPNode
->uiRight
- pclBPNode
->uiLeft
) ||
2373 (ui_diff
<= pclBPNode
->uiTop
- pclBPNode
->uiBottom
) )
2375 ui_diff
= (ui_diff
<< 1);
2377 ui_diff
= ( (ui_diff
- 1) >> 1);
2379 /* std::cerr << "subdivide:" << std::endl;
2380 std::cerr << pclBPNode->uiLeft << ", " << pclBPNode->uiRight << std::endl;
2381 std::cerr << pclBPNode->uiBottom << ", " << pclBPNode->uiTop << std::endl;
2382 std::cerr << ui_diff << std::endl;*/
2384 if(pclBPNode
->uiBottom
+ ui_diff
< pclBPNode
->uiTop
)
2386 if(pclBPNode
->uiLeft
+ ui_diff
< pclBPNode
->uiRight
)
2390 pclBPNode
->aptChildren
[3] = new SBPETreeCell
;
2391 pclBPNode
->aptChildren
[3]->uiBottom
= pclBPNode
->uiBottom
;
2392 pclBPNode
->aptChildren
[3]->uiTop
= pclBPNode
->uiBottom
+ ui_diff
;
2393 pclBPNode
->aptChildren
[3]->uiLeft
= pclBPNode
->uiLeft
;
2394 pclBPNode
->aptChildren
[3]->uiRight
= pclBPNode
->uiLeft
+ ui_diff
;
2395 pclBPNode
->aptChildren
[3]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2396 pclBPNode
->aptChildren
[2] = new SBPETreeCell
;
2397 pclBPNode
->aptChildren
[2]->uiBottom
= pclBPNode
->uiBottom
;
2398 pclBPNode
->aptChildren
[2]->uiTop
= pclBPNode
->aptChildren
[3]->uiTop
;
2399 pclBPNode
->aptChildren
[2]->uiLeft
= pclBPNode
->aptChildren
[3]->uiRight
+ 1;
2400 pclBPNode
->aptChildren
[2]->uiRight
= pclBPNode
->uiRight
;
2401 pclBPNode
->aptChildren
[2]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2402 pclBPNode
->aptChildren
[0] = new SBPETreeCell
;
2403 pclBPNode
->aptChildren
[0]->uiBottom
= pclBPNode
->aptChildren
[3]->uiTop
+ 1;
2404 pclBPNode
->aptChildren
[0]->uiTop
= pclBPNode
->uiTop
;
2405 pclBPNode
->aptChildren
[0]->uiLeft
= pclBPNode
->uiLeft
;
2406 pclBPNode
->aptChildren
[0]->uiRight
= pclBPNode
->aptChildren
[3]->uiRight
;
2407 pclBPNode
->aptChildren
[0]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2408 pclBPNode
->aptChildren
[1] = new SBPETreeCell
;
2409 pclBPNode
->aptChildren
[1]->uiBottom
= pclBPNode
->aptChildren
[0]->uiBottom
;
2410 pclBPNode
->aptChildren
[1]->uiTop
= pclBPNode
->uiTop
;
2411 pclBPNode
->aptChildren
[1]->uiLeft
= pclBPNode
->aptChildren
[2]->uiLeft
;
2412 pclBPNode
->aptChildren
[1]->uiRight
= pclBPNode
->uiRight
;
2413 pclBPNode
->aptChildren
[1]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2414 ComputeBPError(pclBPNode
->aptChildren
[3], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2415 ComputeBPError(pclBPNode
->aptChildren
[2], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2416 ComputeBPError(pclBPNode
->aptChildren
[0], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2417 ComputeBPError(pclBPNode
->aptChildren
[1], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2418 SubdivideBPTree(pclBPNode
->aptChildren
[3], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2419 SubdivideBPTree(pclBPNode
->aptChildren
[2], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2420 SubdivideBPTree(pclBPNode
->aptChildren
[0], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2421 SubdivideBPTree(pclBPNode
->aptChildren
[1], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2427 pclBPNode
->aptChildren
[3] = new SBPETreeCell
;
2428 pclBPNode
->aptChildren
[3]->uiBottom
= pclBPNode
->uiBottom
;
2429 pclBPNode
->aptChildren
[3]->uiTop
= pclBPNode
->uiBottom
+ ui_diff
;
2430 pclBPNode
->aptChildren
[3]->uiLeft
= pclBPNode
->uiLeft
;
2431 pclBPNode
->aptChildren
[3]->uiRight
= pclBPNode
->uiRight
;
2432 pclBPNode
->aptChildren
[3]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2433 pclBPNode
->aptChildren
[2] = NULL
;
2434 pclBPNode
->aptChildren
[0] = new SBPETreeCell
;
2435 pclBPNode
->aptChildren
[0]->uiBottom
= pclBPNode
->aptChildren
[3]->uiTop
+ 1;
2436 pclBPNode
->aptChildren
[0]->uiTop
= pclBPNode
->uiTop
;
2437 pclBPNode
->aptChildren
[0]->uiLeft
= pclBPNode
->uiLeft
;
2438 pclBPNode
->aptChildren
[0]->uiRight
= pclBPNode
->uiRight
;
2439 pclBPNode
->aptChildren
[0]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2440 pclBPNode
->aptChildren
[1] = NULL
;
2441 ComputeBPError(pclBPNode
->aptChildren
[3], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2442 ComputeBPError(pclBPNode
->aptChildren
[0], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2443 SubdivideBPTree(pclBPNode
->aptChildren
[3], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2444 SubdivideBPTree(pclBPNode
->aptChildren
[0], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2447 else if(pclBPNode
->uiLeft
+ ui_diff
< pclBPNode
->uiRight
)
2450 pclBPNode
->aptChildren
[3] = new SBPETreeCell
;
2451 pclBPNode
->aptChildren
[3]->uiBottom
= pclBPNode
->uiBottom
;
2452 pclBPNode
->aptChildren
[3]->uiTop
= pclBPNode
->uiTop
;
2453 pclBPNode
->aptChildren
[3]->uiLeft
= pclBPNode
->uiLeft
;
2454 pclBPNode
->aptChildren
[3]->uiRight
= pclBPNode
->uiLeft
+ ui_diff
;
2455 pclBPNode
->aptChildren
[3]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2456 pclBPNode
->aptChildren
[2] = new SBPETreeCell
;
2457 pclBPNode
->aptChildren
[2]->uiBottom
= pclBPNode
->uiBottom
;
2458 pclBPNode
->aptChildren
[2]->uiTop
= pclBPNode
->uiTop
;
2459 pclBPNode
->aptChildren
[2]->uiLeft
= pclBPNode
->aptChildren
[3]->uiRight
+ 1;
2460 pclBPNode
->aptChildren
[2]->uiRight
= pclBPNode
->uiRight
;
2461 pclBPNode
->aptChildren
[2]->fPrevError
= osgMin(pclBPNode
->fError
, pclBPNode
->fPrevError
);
2462 pclBPNode
->aptChildren
[0] = NULL
;
2463 pclBPNode
->aptChildren
[1] = NULL
;
2464 ComputeBPError(pclBPNode
->aptChildren
[3], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2465 ComputeBPError(pclBPNode
->aptChildren
[2], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2466 SubdivideBPTree(pclBPNode
->aptChildren
[3], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2467 SubdivideBPTree(pclBPNode
->aptChildren
[2], pvvclPatches
, cpvdIntervalsU
, cpvdIntervalsV
);
2471 pclBPNode
->aptChildren
[0] = NULL
;
2472 pclBPNode
->aptChildren
[1] = NULL
;
2473 pclBPNode
->aptChildren
[2] = NULL
;
2474 pclBPNode
->aptChildren
[3] = NULL
;
2479 void CErrorQuadTree::DeleteBPNode(SBPETreeCell
*&rpclNode
)
2481 if(rpclNode
->aptChildren
[0])
2483 DeleteBPNode(rpclNode
->aptChildren
[0]);
2485 if(rpclNode
->aptChildren
[1])
2487 DeleteBPNode(rpclNode
->aptChildren
[1]);
2489 if(rpclNode
->aptChildren
[2])
2491 DeleteBPNode(rpclNode
->aptChildren
[2]);
2493 if(rpclNode
->aptChildren
[3])
2495 DeleteBPNode(rpclNode
->aptChildren
[3]);
2503 #ifndef OSG_DIFF_TO_BILIN
2504 double CErrorQuadTree::computeDistToPlane(const Vec3d cclP
, const Vec3d cclV1
, const Vec3d cclV2
, const Vec3d cclV3
)
2510 cl_diff
= cclP
- cclV1
;
2511 cl_norm
= (cclV2
- cclV1
).cross(cclV3
- cclV1
);
2512 d_quad_size
= cl_norm
.squareLength();
2513 // std::cerr << cclP << cclV1 << cclV2 << cclV3 << std::endl;
2514 if(d_quad_size
> 0.0)
2516 // std::cerr << "qs:" << d_quad_size << std::endl;
2517 cl_norm
*= 1.0 / sqrt(d_quad_size
);
2518 // std::cerr << cl_diff << cl_norm << std::endl;
2519 return osgAbs(cl_diff
.dot(cl_norm
) );
2523 // std::cerr << cl_diff << std::endl;
2524 return sqrt(cl_diff
.squareLength() );
2529 double CErrorQuadTree::computeDistToTriangle(const Vec3d cclP
, const Vec3d cclV1
, const Vec3d cclV2
, const Vec3d cclV3
)
2537 const Vec3d ccl_d1
= cclV2
- cclV1
;
2538 const Vec3d ccl_d2
= cclV3
- cclV1
;
2540 cl_diff
= cclP
- cclV1
;
2541 cl_norm
= ccl_d1
.cross(ccl_d2
);
2542 d_temp
= cl_norm
.squareLength();
2545 cl_norm
*= 1.0 / sqrt(d_temp
);
2546 // project point to triangle plane
2547 d_dist
= cl_diff
.dot(cl_norm
);
2548 cl_proj
= cclP
- cl_norm
* d_dist
;
2549 // std::cerr << ( cl_proj - cclV1 ).dot( cl_norm ) << std::endl;
2550 // check if point is inside triangle
2551 cl_diff
= cl_proj
- cclV1
;
2552 d_temp
= ccl_d1
.dot(cl_diff
) / ccl_d1
.squareLength();
2553 d_temp2
= ccl_d2
.dot(cl_diff
) / ccl_d2
.squareLength();
2554 if( (d_temp
< 0.0) || (d_temp2
< 0.0) || (d_temp
+ d_temp2
> 1.0) )
2556 // std::cerr << d_temp << " " << d_temp2 << ": " << osgAbs( d_dist );
2557 d_dist
= computeDistToLine(cclP
, cclV1
, cclV2
);
2558 d_temp
= computeDistToLine(cclP
, cclV1
, cclV3
);
2561 d_temp
= computeDistToLine(cclP
, cclV2
, cclV3
);
2564 // std::cerr << " -> " << d_dist << std::endl;
2566 return osgAbs(d_dist
);
2570 return sqrt(cl_diff
.squareLength() );
2575 double CErrorQuadTree::computeDistToLine(const Vec3d cclP
, const Vec3d cclV1
, const Vec3d cclV2
)
2577 const Vec3d ccl_d
= cclV2
- cclV1
;
2578 const Vec3d ccl_diff
= cclP
- cclV1
;
2582 d_temp
= ccl_d
.dot(ccl_diff
);
2585 // std::cerr << "a " << sqrt( ccl_diff.squareLength( ) ) << std::endl;
2586 return sqrt(ccl_diff
.squareLength() );
2588 d_temp2
= ccl_d
.squareLength();
2589 if(d_temp2
<= d_temp
)
2591 // std::cerr << "b " << sqrt( ( cclP - cclV2 ).squareLength( ) ) << std::endl;
2592 return sqrt( (cclP
- cclV2
).squareLength() );
2594 // std::cerr << "c " << sqrt( ( ccl_d * ( d_temp / d_temp2 ) - ccl_diff ).squareLength( ) ) << std::endl;
2595 return sqrt( (ccl_d
* (d_temp
/ d_temp2
) - ccl_diff
).squareLength() );
2598 void CErrorQuadTree::WriteTree(std::ostream
&rclFile
)
2600 #ifdef OSG_ARBITRARY_SPLIT
2601 SErrorTreeCell
*pt_act
;
2602 std::vector
<SErrorTreeCell
*> vpt_stack
;
2605 rclFile
<< m_fMaxError
<< std::endl
;
2607 // store error cells
2608 vpt_stack
.push_back(m_ptRoot
);
2609 while(vpt_stack
.size() )
2611 pt_act
= vpt_stack
[vpt_stack
.size() - 1];
2612 vpt_stack
.pop_back();
2613 rclFile
<< pt_act
->fError
<< " " << pt_act
->fSplitValue
<< " ";
2614 rclFile
<< ( (pt_act
->ptChildren
!= NULL
) ? true : false) << std::endl
;
2615 if(pt_act
->ptChildren
!= NULL
)
2617 vpt_stack
.push_back(&(pt_act
->ptChildren
[1]) );
2618 vpt_stack
.push_back(&(pt_act
->ptChildren
[0]) );
2624 void CErrorQuadTree::ReadTree(std::istream
&rclFile
)
2626 #ifdef OSG_ARBITRARY_SPLIT
2627 SErrorTreeCell
*pt_act
;
2628 std::vector
<SErrorTreeCell
*> vpt_stack
;
2629 bool b_has_children
;
2632 rclFile
>> m_fMaxError
>> std::ws
;
2635 m_ptRoot
= new SErrorTreeCell
;
2636 vpt_stack
.push_back(m_ptRoot
);
2637 while(vpt_stack
.size() )
2639 pt_act
= vpt_stack
[vpt_stack
.size() - 1];
2640 vpt_stack
.pop_back();
2641 rclFile
>> pt_act
->fError
>> std::ws
>> pt_act
->fSplitValue
>> std::ws
;
2642 rclFile
>> b_has_children
>> std::ws
;
2645 pt_act
->ptChildren
= new SErrorTreeCell
[2];
2646 vpt_stack
.push_back(&(pt_act
->ptChildren
[1]) );
2647 vpt_stack
.push_back(&(pt_act
->ptChildren
[0]) );
2651 pt_act
->ptChildren
= NULL
;