Add drawing workspace feature
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1 parent
ad73ddec2b
commit
a5cc458252
78 files changed
+35740
-6
No files matched your search
@@ -0,0 +1,31 @@
|
||||
import { Vector3 } from 'three';
|
||||
|
||||
export type DepthFace<T>={vertices:Vector3[];edges:boolean[];data:T};
|
||||
/** BSP painter for an orthographic camera at negative depth. Split crossing faces,
|
||||
* preserving only original edges so partition boundaries never become CAD outlines. */
|
||||
export function visibleOrder<T>(input:DepthFace<T>[]):DepthFace<T>[] {
|
||||
const visit=(faces:DepthFace<T>[]):DepthFace<T>[]=>{
|
||||
if(!faces.length)return [];
|
||||
const seed=faces[0],a=seed.vertices[0];let normal=new Vector3();
|
||||
for(let i=1;i<seed.vertices.length-1&&normal.lengthSq()<1e-16;i++)normal=seed.vertices[i].clone().sub(a).cross(seed.vertices[i+1].clone().sub(a));
|
||||
if(normal.lengthSq()<1e-16)return visit(faces.slice(1));
|
||||
normal.normalize();const offset=normal.dot(a),front:DepthFace<T>[]=[],back:DepthFace<T>[]=[],same:DepthFace<T>[]=[seed];
|
||||
for(const face of faces.slice(1)){
|
||||
const ds=face.vertices.map(p=>normal.dot(p)-offset),positive=ds.some(d=>d>1e-5),negative=ds.some(d=>d< -1e-5);
|
||||
if(!positive&&!negative){same.push(face);continue;}
|
||||
if(!negative){front.push(face);continue;}if(!positive){back.push(face);continue;}
|
||||
for(const [sign,list] of [[1,front],[-1,back]] as const){
|
||||
const vertices:Vector3[]=[],incoming:boolean[]=[];
|
||||
for(let i=0;i<face.vertices.length;i++){
|
||||
const j=(i+1)%face.vertices.length,p=face.vertices[i],q=face.vertices[j],inside=ds[i]*sign>=-1e-5,next=ds[j]*sign>=-1e-5;
|
||||
if(inside&&next){vertices.push(q);incoming.push(face.edges[i]);}
|
||||
else if(inside&&!next){vertices.push(p.clone().lerp(q,ds[i]/(ds[i]-ds[j])));incoming.push(face.edges[i]);}
|
||||
else if(!inside&&next){vertices.push(p.clone().lerp(q,ds[i]/(ds[i]-ds[j])),q);incoming.push(false,face.edges[i]);}
|
||||
}
|
||||
if(vertices.length>=3)list.push({vertices,edges:incoming.map((_,i)=>incoming[(i+1)%incoming.length]),data:face.data});
|
||||
}
|
||||
}
|
||||
return normal.z<0?[...visit(back),...same,...visit(front)]:[...visit(front),...same,...visit(back)];
|
||||
};
|
||||
return visit(input.flatMap(face=>Array.from({length:face.vertices.length-2},(_,j)=>{const i=j+1;return {vertices:[face.vertices[0],face.vertices[i],face.vertices[i+1]],edges:[i===1&&face.edges[0],face.edges[i],i===face.vertices.length-2&&face.edges[i+1]],data:face.data};})));
|
||||
}
|
||||
Reference in new issue
Block a user