/* static */ void FsLazyWindowApplication::YsShellToVtxNom(std::vector <float> &vtx,std::vector <float> &nom,std::vector <float> &col,const YsShellExt &shl) { vtx.clear(); nom.clear(); col.clear(); for(auto plHd : shl.AllPolygon()) { auto plVtHd=shl.GetPolygonVertex(plHd); if(3<=plVtHd.GetN()) { auto plNom=shl.GetNormal(plHd); for(auto vtHd : plVtHd) { auto vtPos=shl.GetVertexPosition(vtHd); vtx.push_back(vtPos.xf()); vtx.push_back(vtPos.yf()); vtx.push_back(vtPos.zf()); nom.push_back(plNom.xf()); nom.push_back(plNom.yf()); nom.push_back(plNom.zf()); col.push_back(0); col.push_back(0); col.push_back(1); col.push_back(0.5); } } } }
YsShell::PolygonHandle FsLazyWindowApplication::PickedTriangle(int mx,int my) const { YsVec3 o,v; drawEnv.TransformScreenCoordTo3DLine(o,v,mx,my); YsShell::PolygonHandle picked=nullptr; double pickedDist=0.0; for(auto plHd : shl.AllPolygon()) { auto plVtHd=shl.GetPolygonVertex(plHd); const YsVec3 tri[3]= { shl.GetVertexPosition(plVtHd[0]), shl.GetVertexPosition(plVtHd[1]), shl.GetVertexPosition(plVtHd[2]), }; YsPlane pln; pln.MakePlaneFromTriangle(tri[0],tri[1],tri[2]); YsVec3 itsc; if(YSOK==pln.GetIntersection(itsc,o,v)) { auto side=YsCheckInsideTriangle3(itsc,tri); if(YSINSIDE==side || YSBOUNDARY==side) { auto dist=(itsc-o)*v; // Gives distance if(0.0<dist && (picked==nullptr || dist<pickedDist)) { picked=plHd; pickedDist=dist; } } } } return picked; }
YSBOOL YsShellExt_RoundUtil3d::IsPolygonOnTheSameContour(const YsShellExt &shl,YsShellPolygonHandle plHd,const YsHashTable <YSSIZE_T> &vtKeyToBoundaryIdx) { auto plVtHd=shl.GetPolygonVertex(plHd); if(0<plVtHd.GetN()) { YSSIZE_T boundaryIdx0; if(YSOK!=vtKeyToBoundaryIdx.FindElement(boundaryIdx0,shl.GetSearchKey(plVtHd[0]))) { return YSFALSE; } for(auto vtHd : plVtHd) { YSSIZE_T boundaryIdx; if(YSOK!=vtKeyToBoundaryIdx.FindElement(boundaryIdx,shl.GetSearchKey(vtHd)) || boundaryIdx!=boundaryIdx0) { return YSFALSE; } } return YSTRUE; } return YSFALSE; }
void YsShellExt_SewingInfo::MakePolygonSplitInfo(const YsShellExt &shl) { // A concave polygon may be cut twice by one crawling. YsShellPolygonAttribTable <YsArray <YsArray <YsShellVertexHandle,2> > > plHdToDivider(shl.Conv()); for(auto &v : vtxSequence) { if(NULL==v.vtHd) { if(0<=v.vtxOnEdgeIdx) { v.vtHd=vtxOnEdge[v.vtxOnEdgeIdx].createdVtHd; } else if(0<=v.vtxOnPlgIdx) { v.vtHd=vtxOnPlg[v.vtxOnPlgIdx].vtHd; } } } { YsShellPolygonHandle currentPlHd=NULL; YsArray <YsShellVertexHandle,2> currentDivider; for(YSSIZE_T idx=0; idx<vtxSequence.GetN(); ++idx) { if(0==currentDivider.GetN()) { currentPlHd=vtxSequence[idx].plHd; currentDivider.Append(vtxSequence[idx].vtHd); } else { currentDivider.Append(vtxSequence[idx].vtHd); if(idx==vtxSequence.GetN()-1 || vtxSequence[idx].plHd!=currentPlHd) { if(2<=currentDivider.GetN()) { YsArray <YsArray <YsShellVertexHandle,2> > *pldv=plHdToDivider[currentPlHd]; if(NULL==pldv) { YsArray <YsArray <YsShellVertexHandle,2> > newDividerArray(1,NULL); newDividerArray[0].MoveFrom(currentDivider); plHdToDivider.SetAttrib(currentPlHd,newDividerArray); } else { pldv->Append(currentDivider); } } currentDivider.CleanUp(); currentDivider.Append(vtxSequence[idx].vtHd); } currentPlHd=vtxSequence[idx].plHd; } } } for(auto hashHd : plHdToDivider.AllHandle()) { auto plKey=plHdToDivider.GetKey(hashHd); auto plHd=shl.FindPolygon(plKey); auto ÷r=*plHdToDivider[plHd]; YsSegmentedArray <YsArray <YsShellVertexHandle,4>,4> plVtHd(1,NULL); plVtHd[0]=shl.GetPolygonVertex(plHd); for(auto d : divider) { YsArray <YsShellVertexHandle,4> fragment; for(auto &pl : plVtHd) { if(YSOK==YsShellExt_SplitLoopByHandleAndMidNode(pl,fragment,d)) { plVtHd.Append(fragment); break; } } } plgSplit.Increment(); plgSplit.Last().plHd=plHd; plgSplit.Last().plVtHdArray=plVtHd; } }