/*static*/ YsArray <double> YsShellExt_SweepInfoMultiStep::CalculateScalingForParallelSweepWithPathAndGuideLine( const YsVec3 &sweepDir,const YsArray <YsVec3> &pathArray,const YsArray <YsVec3> &guideArray) { if(1>=pathArray.GetN() || 1>=guideArray.GetN()) { YsArray <double> empty; return empty; } YsArray <double> scaling(pathArray.GetN(),NULL); for(auto &s : scaling) { s=1.0; } for(auto pathIndex : pathArray.AllIndex()) { auto &s=scaling[pathIndex]; auto &pathPnt=pathArray[pathIndex]; const YsPlane cutPln(pathPnt,sweepDir); YSBOOL done=YSFALSE; for(auto &guidePos : guideArray) { if(YSTRUE==cutPln.CheckOnPlane(guidePos)) { s=(guidePos-pathPnt).GetLength(); done=YSTRUE; break; } } if(YSTRUE!=done) { for(auto guideIndex : guideArray.AllIndex()) { if(guideIndex<guideArray.GetN()-1) { auto &pos0=guideArray[guideIndex]; auto &pos1=guideArray[guideIndex+1]; YsVec3 itsc; if(YSOK==cutPln.GetPenetrationHighPrecision(itsc,pos0,pos1)) { s=(itsc-pathPnt).GetLength(); done=YSTRUE; break; } else if(0==guideIndex) { if(YSOK==cutPln.GetIntersection(itsc,pos0,pos1-pos0) && (0.0<(itsc-pos0)*(pos0-pos1) || 2==guideArray.GetN())) // If guideArray consists of only two points, which side of line doesn't matter. { s=(itsc-pathPnt).GetLength(); done=YSTRUE; break; } } else if(guideArray.GetN()-2==guideIndex) { if(YSOK==cutPln.GetIntersection(itsc,pos0,pos1-pos0) && 0.0<(itsc-pos1)*(pos1-pos0)) { s=(itsc-pathPnt).GetLength(); done=YSTRUE; break; } } } } } } const double ref=scaling[0]; for(auto &s : scaling) { s/=ref; } scaling[0]=1.0; return scaling; }
YSRESULT YsShellExt_RoundUtil3d::SetUpForVertexSequenceAndPolygonArray( const YsShellExt &shl, const YsArray <YsArray <YsShellVertexHandle> > &allBoundary, const YsArray <YsShellPolygonHandle> &sideAPolygonArray, const YsArray <YsShellPolygonHandle> &sideBPolygonArray) { YsHashTable <YSSIZE_T> vtKeyToBoundaryIdx; YsShellEdgeStore boundaryEdge((const YsShell &)shl); for(auto idx : allBoundary.AllIndex()) { YsArray <YsShellVertexHandle> contourVtHd=allBoundary[idx]; for(YSSIZE_T vtIdx=0; vtIdx<contourVtHd.GetN()-1; ++vtIdx) { if(YSTRUE!=boundaryEdge.IsIncluded(contourVtHd[vtIdx],contourVtHd[vtIdx+1])) { boundaryEdge.AddEdge(contourVtHd[vtIdx],contourVtHd[vtIdx+1]); roundEdgeArray.Increment(); roundEdgeArray.Last().Initialize(); roundEdgeArray.Last().edVtHd[0]=contourVtHd[vtIdx]; roundEdgeArray.Last().edVtHd[1]=contourVtHd[vtIdx+1]; } } for(auto vtHd : contourVtHd) { vtKeyToBoundaryIdx.AddElement(shl.GetSearchKey(vtHd),idx); } } // Boundary edge hash and sideBPolygon store have been constructed. YsShellExt_OffsetUtil2d &sideAOffset=offsetUtil[0],&sideBOffset=offsetUtil[1]; YsShellPolygonStore sideAPolygon((const YsShell &)shl),sideBPolygon((const YsShell &)shl); sideAPolygon.AddPolygon(sideAPolygonArray); sideBPolygon.AddPolygon(sideBPolygonArray); YSBOOL sideAOffsetNecessary=YSFALSE,sideBOffsetNecessary=YSFALSE; if(YSTRUE==alwaysUseOffset) { sideAOffsetNecessary=YSTRUE; sideBOffsetNecessary=YSTRUE; } else { for(auto boundary : allBoundary) { YsArray <YsShellVertexHandle> contourVtHd=boundary; for(auto vtHd : contourVtHd) { YsArray <YsShellVertexHandle,16> connVtHdArray; shl.GetConnectedVertex(connVtHdArray,vtHd); YSBOOL sideAEdgePresent=YSFALSE,sideBEdgePresent=YSFALSE; for(auto connVtHd : connVtHdArray) { if(YSTRUE==boundaryEdge.IsIncluded(vtHd,connVtHd)) { continue; } if(YSTRUE==IsEdgeUsing(vtHd,connVtHd,shl.Conv(),sideAPolygon)) { sideAEdgePresent=YSTRUE; } else if(YSTRUE==IsEdgeUsing(vtHd,connVtHd,shl.Conv(),sideBPolygon)) { sideBEdgePresent=YSTRUE; } } if(YSTRUE!=sideAEdgePresent) { sideAOffsetNecessary=YSTRUE; } if(YSTRUE!=sideBEdgePresent) { sideBOffsetNecessary=YSTRUE; } } } } printf("%s %d\n",__FUNCTION__,__LINE__); printf("%d %d\n",sideAOffsetNecessary,sideBOffsetNecessary); if(YSTRUE==sideAOffsetNecessary) { if(YSOK!=sideAOffset.SetUpForOneSideOfVertexSequence(shl,allBoundary,sideAPolygonArray)) { return YSERR; } for(YSSIZE_T idx=0; idx<sideAOffset.newVtxArray.GetN(); ++idx) { auto newVtx=sideAOffset.newVtxArray[idx]; cornerArray.Increment(); cornerArray.Last().Initialize(); cornerArray.Last().fromVtHd=newVtx.fromVtHd; cornerArray.Last().toVtHd=NULL; cornerArray.Last().toPos=newVtx.fromPos+newVtx.dir*newVtx.maxDist; cornerArray.Last().offsetUtil=&sideAOffset; cornerArray.Last().offsetUtil_newVtxIdx=idx; cornerArray.Last().notReallyDistanceLimited=IsPolygonOnTheSameContour(shl,newVtx.limitingPlHd,vtKeyToBoundaryIdx); } } if(YSTRUE==sideBOffsetNecessary) { if(YSOK!=sideBOffset.SetUpForOneSideOfVertexSequence(shl,allBoundary,sideBPolygonArray)) { return YSERR; } for(YSSIZE_T idx=0; idx<sideBOffset.newVtxArray.GetN(); ++idx) { auto newVtx=sideBOffset.newVtxArray[idx]; cornerArray.Increment(); cornerArray.Last().Initialize(); cornerArray.Last().fromVtHd=newVtx.fromVtHd; cornerArray.Last().toVtHd=NULL; cornerArray.Last().toPos=newVtx.fromPos+newVtx.dir*newVtx.maxDist; cornerArray.Last().offsetUtil=&sideBOffset; cornerArray.Last().offsetUtil_newVtxIdx=idx; cornerArray.Last().notReallyDistanceLimited=IsPolygonOnTheSameContour(shl,newVtx.limitingPlHd,vtKeyToBoundaryIdx); } } printf("%s %d\n",__FUNCTION__,__LINE__); for(auto boundary : allBoundary) { YsArray <YsShellVertexHandle> contourVtHd=boundary; if(3<=contourVtHd.GetN()) { if(contourVtHd[0]==contourVtHd.Last()) { contourVtHd.DeleteLast(); } } for(auto vtHd : contourVtHd) { YsArray <YsShellVertexHandle,16> connVtHdArray; shl.GetConnectedVertex(connVtHdArray,vtHd); for(auto connVtHd : connVtHdArray) { if(YSTRUE==boundaryEdge.IsIncluded(vtHd,connVtHd)) { continue; } else if((YSTRUE!=sideAOffsetNecessary && YSTRUE==IsEdgeUsing(vtHd,connVtHd,(const YsShell &)shl,sideAPolygon)) || (YSTRUE!=sideBOffsetNecessary && YSTRUE==IsEdgeUsing(vtHd,connVtHd,(const YsShell &)shl,sideBPolygon))) { cornerArray.Increment(); cornerArray.Last().Initialize(); cornerArray.Last().fromVtHd=vtHd; cornerArray.Last().toVtHd=connVtHd; cornerArray.Last().toPos=shl.GetVertexPosition(connVtHd); } } } } printf("%s %d\n",__FUNCTION__,__LINE__); for(YSSIZE_T cornerIdx=0; cornerIdx<cornerArray.GetN(); ++cornerIdx) { if(NULL!=cornerArray[cornerIdx].offsetUtil) { cornerArray[cornerIdx].offsetUtil->newVtxArray[cornerArray[cornerIdx].offsetUtil_newVtxIdx].cornerIdx=cornerIdx; } } printf("%s %d\n",__FUNCTION__,__LINE__); if(YSOK==CalculateRoundingDirectionAll((const YsShell &)shl)) { printf("%s %d\n",__FUNCTION__,__LINE__); return YSOK; } printf("%s %d\n",__FUNCTION__,__LINE__); CleanUp(); return YSERR; }