// @@sbr This method should be moved to BoundedSurface. The method is // not that straight forward when handling other closed sfs as we may // not assume that the surface is cyclic with a common period. For // these cases we may have to split the surface up into smaller // pieces. And then it makes sense to use an external routine // (i.e. not a BoundedSurface member function). bool fixParCvCrossingCylinderSeem(BoundedSurface* trimmed_cyl) { MESSAGE("Under construction!"); if (trimmed_cyl->underlyingSurface()->instanceType() != Class_Cylinder) { return false; } Cylinder* cyl = dynamic_cast<Cylinder*>(trimmed_cyl->underlyingSurface().get()); bool params_swapped = cyl->isSwapped(); RectDomain rect_dom = cyl->containingDomain(); // We may not assume that the cylinder is parametrized on [0, 2*M_PI). // We run through all the bd_cvs, extracting the convex hull of // the coefs of the parameter cvs. Comparing this with the domain // of the cylinder we can decide if we should and are able to move // the seem. We only need to look at the outer loop (the first) // to test for crossing of seem and possibly the translation // vector. shared_ptr<CurveLoop> outer_loop = trimmed_cyl->loop(0); vector<BoundingBox> par_bd_boxes; vector<ParamCurve*> par_cvs(outer_loop->size()); #ifndef NDEBUG CurveOnSurface* first_cv_on_sf = dynamic_cast<CurveOnSurface*>((*outer_loop)[0].get()); assert(first_cv_on_sf != NULL); Point space_cv_pt = first_cv_on_sf->spaceCurve()->point(first_cv_on_sf->spaceCurve()->startparam()); Point par_cv_pt = first_cv_on_sf->parameterCurve()->point(first_cv_on_sf->parameterCurve()->startparam()); Point sf_pt = cyl->ParamSurface::point(par_cv_pt[0], par_cv_pt[1]); #endif for (size_t ki = 0; ki < outer_loop->size(); ++ki) { CurveOnSurface* cv_on_sf = dynamic_cast<CurveOnSurface*>((*outer_loop)[ki].get()); assert(cv_on_sf != 0); ParamCurve* par_cv = cv_on_sf->parameterCurve().get(); par_cvs[ki] = par_cv; if (par_cv != 0) { BoundingBox par_bd_box(2); SplineCurve* spline_cv = par_cv->geometryCurve(); Point lin_dir; double eps = 1e-05; if (spline_cv != NULL) { // Not handling rational cases at the moment. assert(!spline_cv->rational()); // vector<double> par_bd_box.setFromArray(spline_cv->coefs_begin(), spline_cv->coefs_end(), 2); } else if (par_cv->isLinear(lin_dir, eps)) { vector<Point> pts(2); pts[0] = par_cv->point(par_cv->startparam()); pts[1] = par_cv->point(par_cv->endparam()); par_bd_box.setFromPoints(pts); } else { MESSAGE("Case not handled!"); return false; } par_bd_boxes.push_back(par_bd_box); } } // We then run through all the bd_box elements, checking if they line inside the RectDomain of the cylinder. // We may assume that the cylinder is closed in the u-direction. bool closed_dir_u, closed_dir_v; cyl->isClosed(closed_dir_u, closed_dir_v); if (params_swapped) { std::swap(closed_dir_u, closed_dir_v); } assert(closed_dir_u && (!closed_dir_v)); double umin = rect_dom.umin(); double umax = rect_dom.umax(); double u_low = umax; double u_high = umin; for (size_t ki = 0; ki < par_bd_boxes.size(); ++ki) { Point low = par_bd_boxes[ki].low(); if (low[0] < u_low) { u_low = low[0]; } Point high = par_bd_boxes[ki].high(); if (high[0] > u_high) { u_high = high[0]; } } if ((u_low < umin) || (u_high > umax)) { MESSAGE("A parameter curve lies outside the domain of the cylinder! u_low = " << u_low << ", u_high = " << u_high); // We rotate the cylinder (parametrization) such that the seem does not cross a parameter curve. // double transl_u = (u_low < umin) ? umin - u_low : umax - u_high; double u_span = u_high - u_low; double new_u_low = umax; double new_u_high = umin; vector<double> transl_u(par_bd_boxes.size(), 0.0); if (u_span > umax - umin) { // For some cases the only option is to split the bd_sf into multiple sfs. // We could try to move the segment by 2*M_PI and then move the seem on the other side. for (size_t ki = 0; ki < par_bd_boxes.size(); ++ki) { Point low = par_bd_boxes[ki].low(); Point high = par_bd_boxes[ki].high(); if (low[0] < (umin - u_low)) { cout << "ki = " << ki << ", translate = " << 2*M_PI << endl; transl_u[ki] = 2*M_PI; if (low[0] + 2*M_PI < new_u_low) { new_u_low = low[0] + 2*M_PI; } if (high[0] + 2*M_PI > new_u_high) { new_u_high = high[0] + 2*M_PI; } } else { if (low[0] < new_u_low) { new_u_low = low[0]; } if (high[0] > new_u_high) { new_u_high = high[0]; } } } } u_span = new_u_high - new_u_low; if (u_span > 2*M_PI) { // We next run through all cvs setting the common translation. MESSAGE("Moving of seem is not enough to handle this case, u_span = " << u_span); } // new_u_low will be the value used for moving the seem. for (size_t ki = 0; ki < par_bd_boxes.size(); ++ki) { transl_u[ki] -= new_u_low; cout << "transl_u[ki] = " << transl_u[ki] << endl; } // We then run through the par_cvs translating the u-values of the coefs. cout << "DEBUG: Soon we will handle this case!" << endl; // We rotate the cylinder by u_low - new_u_low. double rot_ang_deg = new_u_low; cyl->rotate(rot_ang_deg); // Finally we run through all curve segments and perfomr the translation in the u-dir. for (size_t ki = 0; ki < par_cvs.size(); ++ki) { if (par_cvs[ki] != NULL) { if (par_cvs[ki]->instanceType() == Class_SplineCurve) { SplineCurve* spline_cv = dynamic_cast<SplineCurve*>(par_cvs[ki]); vector<double>::iterator iter = spline_cv->coefs_begin(); while (iter != spline_cv->coefs_end()) { iter[0] += transl_u[ki]; iter += 2; } } else if (par_cvs[ki]->instanceType() == Class_Line) { Line* line = dynamic_cast<Line*>(par_cvs[ki]); Point transl_vec(2, 0.0); transl_vec[0] = transl_u[ki]; line->translateCurve(transl_vec); } else { THROW("Unsupported curve type: " << par_cvs[ki]->instanceType()); } } } #ifndef NDEBUG std::ofstream debug("tmp/debug.g2"); cyl->writeStandardHeader(debug); cyl->write(debug); for (size_t ki = 0; ki < outer_loop->size(); ++ki) { shared_ptr<ParamCurve> cv = (*outer_loop)[ki]; if (cv->instanceType() == Class_CurveOnSurface) { shared_ptr<CurveOnSurface> cv_on_sf = dynamic_pointer_cast<CurveOnSurface, ParamCurve>(cv); if (cv_on_sf->parameterCurve() != NULL) { shared_ptr<SplineCurve> pcv = dynamic_pointer_cast<SplineCurve, ParamCurve> (cv_on_sf->parameterCurve()); if (pcv.get() != NULL) SplineDebugUtils::writeSpaceParamCurve(*pcv, debug, 0.0); else { cv_on_sf->parameterCurve()->writeStandardHeader(debug); cv_on_sf->parameterCurve()->write(debug); } } if (cv_on_sf->spaceCurve() != NULL) { cv_on_sf->spaceCurve()->writeStandardHeader(debug); cv_on_sf->spaceCurve()->write(debug); } } else { cv->writeStandardHeader(debug); cv->write(debug); } } double debug_val = 0.0; #endif #ifndef NDEBUG // CurveOnSurface* first_cv_on_sf = dynamic_cast<CurveOnSurface*>((*outer_loop)[0].get()); // assert(first_cv_on_sf != NULL); Point new_space_cv_pt = first_cv_on_sf->spaceCurve()->point(first_cv_on_sf->spaceCurve()->startparam()); Point new_par_cv_pt = first_cv_on_sf->parameterCurve()->point(first_cv_on_sf->parameterCurve()->startparam()); Point new_sf_pt = cyl->ParamSurface::point(new_par_cv_pt[0], new_par_cv_pt[1]); #endif trimmed_cyl->analyzeLoops(); return true; } return false; }
void Handle::initAxisHandleObjects() { // assumes none of them have been created yet Handle::pObjectXTranslateHandleLine = new Cylinder(1.0f, 0.03f, 6, 1); Handle::pObjectYTranslateHandleLine = new Cylinder(1.0f, 0.03f, 6, 1); Handle::pObjectZTranslateHandleLine = new Cylinder(1.0f, 0.03f, 6, 1); Handle::pObjectXTranslateHandleHead = new Cone(0.2f, 0.07f, 8); Handle::pObjectYTranslateHandleHead = new Cone(0.2f, 0.07f, 8); Handle::pObjectZTranslateHandleHead = new Cone(0.2f, 0.07f, 8); Cylinder *pX = Handle::pObjectXTranslateHandleLine; Cylinder *pY = Handle::pObjectYTranslateHandleLine; Cylinder *pZ = Handle::pObjectZTranslateHandleLine; pX->setObjectID(eXTranslate); pX->setPosition(Point(0.6f, 0.0f, 0.0f)); pX->rotate(0.0f, 0.0f, 90.0f); pX->constructGeometry(); pY->setObjectID(eYTranslate); pY->setPosition(Point(0.0f, 0.6f, 0.0f)); pY->constructGeometry(); pZ->setObjectID(eZTranslate); pZ->setPosition(Point(0.0f, 0.0f, 0.6f)); pZ->rotate(-90.0f, 0.0f, 0.0f); pZ->constructGeometry(); Cone *pXHead = Handle::pObjectXTranslateHandleHead; Cone *pYHead = Handle::pObjectYTranslateHandleHead; Cone *pZHead = Handle::pObjectZTranslateHandleHead; pXHead->setObjectID(eXTranslate); pXHead->setPosition(Point(1.1f, 0.0f, 0.0f)); pXHead->rotate(0.0f, 0.0f, -90.0f); pXHead->constructGeometry(); pYHead->setObjectID(eYTranslate); pYHead->setPosition(Point(0.0f, 1.1f, 0.0f)); pYHead->constructGeometry(); pZHead->setObjectID(eZTranslate); pZHead->setPosition(Point(0.0f, 0.0f, 1.1f)); pZHead->rotate(90.0f, 0.0f, 0.0f); pZHead->constructGeometry(); /// object rotate Torus* pXRotate = new Torus(kObjectRotateHandleThickness, kObjectRotateHandleRadius, kObjectRotateHandleSegments, kObjectRotateHandleSides); Torus* pYRotate = new Torus(kObjectRotateHandleThickness, kObjectRotateHandleRadius, kObjectRotateHandleSegments, kObjectRotateHandleSides); Torus* pZRotate = new Torus(kObjectRotateHandleThickness, kObjectRotateHandleRadius, kObjectRotateHandleSegments, kObjectRotateHandleSides); Handle::pObjectXRotateHandleLoop = pXRotate; Handle::pObjectYRotateHandleLoop = pYRotate; Handle::pObjectZRotateHandleLoop = pZRotate; pXRotate->setObjectID(eXRotate); pXRotate->rotate(0.0f, 0.0f, -90.0f); pXRotate->constructGeometry(); pYRotate->setObjectID(eYRotate); pYRotate->rotate(0.0f, 0.0f, 0.0f); pYRotate->constructGeometry(); pZRotate->setObjectID(eZRotate); pZRotate->rotate(90.0f, 0.0f, 0.0f); pZRotate->constructGeometry(); /// face Handle::pFaceNormalTranslateHandleLine = new Cylinder(1.0f, 0.03f, 6, 1); Handle::pFaceNormalTranslateHandleHead = new Cone(0.2f, 0.07f, 8); Handle::pFaceExtrude = new Cube(0.05f); Cylinder* pFaceNormalLine = Handle::pFaceNormalTranslateHandleLine; pFaceNormalLine->setObjectID(eFaceNormalTranslate); pFaceNormalLine->setPosition(Point(0.0f, 0.6f, 0.0f)); pFaceNormalLine->constructGeometry(); Cone* pFaceNormalHead = Handle::pFaceNormalTranslateHandleHead; pFaceNormalHead->setObjectID(eFaceNormalTranslate); pFaceNormalHead->setPosition(Point(0.0f, 1.1f, 0.0f)); pFaceNormalHead->constructGeometry(); Cube* pFaceExtrude = Handle::pFaceExtrude; pFaceExtrude->setObjectID(eFaceExtrude); pFaceExtrude->setPosition(Point(0.0f, 1.4f, 0.0f)); pFaceExtrude->constructGeometry(); Handle::pFaceTranslateXLine = new Cylinder(1.0f, 0.03f, 6, 1); Handle::pFaceTranslateYLine = new Cylinder(1.0f, 0.03f, 6, 1); Cylinder* pFaceTranslateXLine = Handle::pFaceTranslateXLine; pFaceTranslateXLine->setObjectID(eFaceTranslateX); pFaceTranslateXLine->setRotation(Vector(0.0f, 0.0f, -90.0f)); pFaceTranslateXLine->setPosition(Point(0.6f, 0.0f, 0.0f)); pFaceTranslateXLine->constructGeometry(); Cylinder* pFaceTranslateYLine = Handle::pFaceTranslateYLine; pFaceTranslateYLine->setObjectID(eFaceTranslateY); pFaceTranslateYLine->setRotation(Vector(90.0f, 0.0f, 0.0f)); pFaceTranslateYLine->setPosition(Point(0.0f, 0.0f, 0.6f)); pFaceTranslateYLine->constructGeometry(); Handle::pFaceTranslateXHead = new Cone(0.2f, 0.07f, 8); Handle::pFaceTranslateYHead = new Cone(0.2f, 0.07f, 8); Cone* pFaceTranslateXHead = Handle::pFaceTranslateXHead; pFaceTranslateXHead->setObjectID(eFaceTranslateX); pFaceTranslateXHead->setRotation(Vector(0.0f, 0.0f, -90.0f)); pFaceTranslateXHead->setPosition(Point(1.1f, 0.0f, 0.0f)); pFaceTranslateXHead->constructGeometry(); Cone* pFaceTranslateYHead = Handle::pFaceTranslateYHead; pFaceTranslateYHead->setObjectID(eFaceTranslateY); pFaceTranslateYHead->setRotation(Vector(90.0f, 0.0f, 0.0f)); pFaceTranslateYHead->setPosition(Point(0.0f, 0.0f, 1.1f)); pFaceTranslateYHead->constructGeometry(); // Handle::pFaceScaleX = new Cube(0.05f); Handle::pFaceScaleY = new Cube(0.05f); Handle::pFaceScaleUniform = new Cube(0.05f); Cube* pFaceScaleX = Handle::pFaceScaleX; pFaceScaleX->setObjectID(eFaceScaleX); pFaceScaleX->setPosition(Point(1.4f, 0.0f, 0.0f)); pFaceScaleX->setRotation(Vector(-90.0f, 0.0f, 0.0f)); pFaceScaleX->constructGeometry(); Cube* pFaceScaleY = Handle::pFaceScaleY; pFaceScaleY->setObjectID(eFaceScaleY); pFaceScaleY->setPosition(Point(0.0f, 0.0f, 1.4f)); pFaceScaleY->constructGeometry(); Cube* pFaceScaleUniform = Handle::pFaceScaleUniform; pFaceScaleUniform->setObjectID(eFaceScaleUniform); pFaceScaleUniform->setPosition(Point(1.4f, 0.0f, 1.4f)); pFaceScaleUniform->constructGeometry(); }