Skip to content

Commit

Permalink
✨ feat: Add selection filters and multiple types of choices
Browse files Browse the repository at this point in the history
Multiple shape types can be selected when selecting, and filter conditions can be added to the target shape at the same time
  • Loading branch information
xiangechen committed Sep 16, 2023
1 parent 71561c7 commit 952e2cd
Show file tree
Hide file tree
Showing 22 changed files with 261 additions and 81 deletions.
5 changes: 5 additions & 0 deletions packages/chili-core/src/geometry/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ export namespace ICurve {
let circle = curve as ICircle;
return circle.center !== undefined && circle.radius !== undefined;
}

export function isLine(curve: ICurve): curve is ILine {
let line = curve as ILine;
return line.direction !== undefined;
}
}
2 changes: 2 additions & 0 deletions packages/chili-core/src/geometry/shape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export interface IShape extends ISerialize {
get mesh(): IShapeMeshData;
setMatrix(matrix: Matrix4): void;
isEqual(other: IShape): boolean;
findAncestor(ancestorType: ShapeType, fromShape: IShape): IShape[];
findSubShapes(subshapeType: ShapeType, unique: boolean): IShape[];
}

export interface IVertex extends IShape {}
Expand Down
45 changes: 36 additions & 9 deletions packages/chili-core/src/geometry/shapeType.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

export enum ShapeType {
Compound,
CompoundSolid,
Solid,
Shell,
Face,
Wire,
Edge,
Vertex,
Shape,
Shape = 0b0,
Compound = 0b1,
CompoundSolid = 0b10,
Solid = 0b100,
Shell = 0b1000,
Face = 0b10000,
Wire = 0b100000,
Edge = 0b1000000,
Vertex = 0b10000000,
}

export namespace ShapeType {
export function hasCompound(type: ShapeType): boolean {
return (type & ShapeType.Compound) !== 0;
}
export function hasCompoundSolid(type: ShapeType): boolean {
return (type & ShapeType.CompoundSolid) !== 0;
}
export function hasSolid(type: ShapeType): boolean {
return (type & ShapeType.Solid) !== 0;
}
export function hasShell(type: ShapeType): boolean {
return (type & ShapeType.Shell) !== 0;
}
export function hasFace(type: ShapeType): boolean {
return (type & ShapeType.Face) !== 0;
}
export function hasWire(type: ShapeType): boolean {
return (type & ShapeType.Wire) !== 0;
}
export function hasEdge(type: ShapeType): boolean {
return (type & ShapeType.Edge) !== 0;
}
export function hasVertex(type: ShapeType): boolean {
return (type & ShapeType.Vertex) !== 0;
}
}
2 changes: 1 addition & 1 deletion packages/chili-core/src/visual/detectedData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import { IVisualShape } from "./visualShape";
export interface VisualShapeData {
shape: IShape;
owner: IVisualShape;
index?: number;
indexes: number[];
}
1 change: 1 addition & 0 deletions packages/chili-core/src/visual/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
export * from "./cursorType";
export * from "./detectedData";
export * from "./eventHandler";
export * from "./shapeFilter";
export * from "./view";
export * from "./viewer";
export * from "./visual";
Expand Down
7 changes: 7 additions & 0 deletions packages/chili-core/src/visual/shapeFilter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { IShape } from "../geometry";

export interface IShapeFilter {
allow(shape: IShape): boolean;
}
12 changes: 10 additions & 2 deletions packages/chili-core/src/visual/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ShapeType } from "../geometry";
import { Plane, Ray, XY, XYZ } from "../math";
import { CursorType } from "./cursorType";
import { VisualShapeData } from "./detectedData";
import { IShapeFilter } from "./shapeFilter";
import { IViewer } from "./viewer";

export interface IView extends IPropertyChanged {
Expand All @@ -26,8 +27,15 @@ export interface IView extends IPropertyChanged {
pan(dx: number, dy: number): void;
rotation(dx: number, dy: number): void;
zoom(x: number, y: number, delta: number): void;
detected(shapeType: ShapeType, x: number, y: number): VisualShapeData[];
rectDetected(shapeType: ShapeType, x1: number, y1: number, x2: number, y2: number): VisualShapeData[];
detected(shapeType: ShapeType, x: number, y: number, shapeFilter?: IShapeFilter): VisualShapeData[];
rectDetected(
shapeType: ShapeType,
x1: number,
y1: number,
x2: number,
y2: number,
shapeFilter?: IShapeFilter,
): VisualShapeData[];
}

export namespace IView {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili-core/src/visual/visualShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface VisualGroup {

export interface IVisualShape extends IVisualObject {
get shape(): IShape;
addState(state: VisualState, type: ShapeType, index?: number): void;
removeState(state: VisualState, type: ShapeType, index?: number): void;
addState(state: VisualState, type: ShapeType, ...indexes: number[]): void;
removeState(state: VisualState, type: ShapeType, ...indexes: number[]): void;
resetState(): void;
}
14 changes: 8 additions & 6 deletions packages/chili-occ/src/occHelps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ export class OccHelps {
return occ.TopAbs_ShapeEnum.TopAbs_EDGE as TopAbs_ShapeEnum;
case ShapeType.Vertex:
return occ.TopAbs_ShapeEnum.TopAbs_VERTEX as TopAbs_ShapeEnum;
default:
case ShapeType.Shape:
return occ.TopAbs_ShapeEnum.TopAbs_SHAPE as TopAbs_ShapeEnum;
default:
throw new Error("Unknown shape type: " + shapeType);
}
}

Expand Down Expand Up @@ -218,14 +220,14 @@ export class OccHelps {
const hashes = unique ? new Map() : undefined;
while (explorer.More()) {
const item = explorer.Current();
if (!unique) {
yield item;
} else {
if (unique) {
const hash = OccHelps.hashCode(item);
if (!hashes?.has(hash)) {
hashes?.set(hash, true);
if (!hashes!.has(hash)) {
hashes!.set(hash, true);
yield this.getActualShape(item);
}
} else {
yield item;
}
explorer.Next();
}
Expand Down
10 changes: 9 additions & 1 deletion packages/chili-occ/src/occShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,15 @@ export class OccShape implements IShape {
return tshape;
}

findSubShapes(shapeType: ShapeType, unique: boolean = false): IShape[] {
findAncestor(ancestorType: ShapeType, fromShape: IShape): IShape[] {
if (!(fromShape instanceof OccShape)) {
throw new Error(`${fromShape} is not an OccShape`);
}
let occType = OccHelps.getShapeEnum(ancestorType);
return OccHelps.findAncestors(this.shape, fromShape.shape, occType).map((x) => OccHelps.getShape(x));
}

findSubShapes(shapeType: ShapeType, unique: boolean): IShape[] {
let result = new Array<IShape>();
let iter = OccHelps.findSubShapes(this.shape, OccHelps.getShapeEnum(shapeType), unique);
for (const it of iter) {
Expand Down
22 changes: 11 additions & 11 deletions packages/chili-occ/test/occ.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,19 @@ describe("shape test", () => {
let end = new occ.gp_Pnt_3(10, 0, 0);
let make = new occ.BRepBuilderAPI_MakeEdge_3(start, end);
let edge = new OccEdge(make.Edge());
expect(edge.findSubShapes(ShapeType.Edge).length).toBe(1);
expect(edge.findSubShapes(ShapeType.Vertex).length).toBe(2);
expect(edge.findSubShapes(ShapeType.Shape).length).toBe(0);
expect(edge.findSubShapes(ShapeType.Edge, false).length).toBe(1);
expect(edge.findSubShapes(ShapeType.Vertex, false).length).toBe(2);
expect(edge.findSubShapes(ShapeType.Shape, false).length).toBe(0);

let make2 = new occ.BRepPrimAPI_MakeBox_2(10, 10, 10);
let box = new OccSolid(make2.Solid());
expect(box.findSubShapes(ShapeType.Edge).length).toBe(24);
expect(box.findSubShapes(ShapeType.Face).length).toBe(6);
expect(box.findSubShapes(ShapeType.Vertex).length).toBe(48);
expect(box.findSubShapes(ShapeType.Wire).length).toBe(6);
expect(box.findSubShapes(ShapeType.Shell).length).toBe(1);
expect(box.findSubShapes(ShapeType.Shell)[0].shapeType).toBe(ShapeType.Shell);
expect(box.findSubShapes(ShapeType.Shape).length).toBe(0);
expect(box.findSubShapes(ShapeType.Edge, false).length).toBe(24);
expect(box.findSubShapes(ShapeType.Face, false).length).toBe(6);
expect(box.findSubShapes(ShapeType.Vertex, false).length).toBe(48);
expect(box.findSubShapes(ShapeType.Wire, false).length).toBe(6);
expect(box.findSubShapes(ShapeType.Shell, false).length).toBe(1);
expect(box.findSubShapes(ShapeType.Shell, false)[0].shapeType).toBe(ShapeType.Shell);
expect(box.findSubShapes(ShapeType.Shape, false).length).toBe(0);

let v1s: any[] = [];
let iter = box.iterSubShapes(ShapeType.Vertex);
Expand All @@ -82,7 +82,7 @@ describe("shape test", () => {
test("test ancestors", () => {
let make2 = new occ.BRepPrimAPI_MakeBox_2(10, 10, 10);
let box = new OccSolid(make2.Solid());
let edge = box.findSubShapes(ShapeType.Edge)[0] as any;
let edge = box.findSubShapes(ShapeType.Edge, false)[0] as any;
let wire = OccHelps.findAncestors(edge.shape, box.shape, OccHelps.getShapeEnum(ShapeType.Wire));
expect(wire.length).toBe(2);
expect(wire[0].ShapeType()).toBe(OccHelps.getShapeEnum(ShapeType.Wire));
Expand Down
36 changes: 27 additions & 9 deletions packages/chili-three/src/threeShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,34 @@ export class ThreeShape extends Object3D implements IVisualShape {
}
}

addState(state: VisualState, type: ShapeType, index?: number) {
let newState = this.updateState("add", state, type, index);
this.setState(type, newState, index);
addState(state: VisualState, type: ShapeType, ...indexes: number[]) {
this.removeOrAddState("add", state, type, ...indexes);
}

removeState(state: VisualState, type: ShapeType, index?: number) {
let newState = this.updateState("remove", state, type, index);
this.setState(type, newState, index);
removeState(state: VisualState, type: ShapeType, ...indexes: number[]) {
this.removeOrAddState("remove", state, type, ...indexes);
}

private setState(type: ShapeType, newState: VisualState, index: number | undefined) {
private removeOrAddState(
action: "remove" | "add",
state: VisualState,
type: ShapeType,
...indexes: number[]
) {
const setState = (index?: number) => {
let newState = this.updateState(action, state, type, index);
this.setState(type, newState, index);
};
if (indexes.length === 0) {
setState();
} else {
indexes.forEach((index) => {
setState(index);
});
}
}

private setState(type: ShapeType, newState: VisualState, index?: number) {
const setFaceState = () => {
if (this._faces) this.setGroupsMaterial(this._faces.geometry, newState, index);
};
Expand All @@ -153,9 +170,10 @@ export class ThreeShape extends Object3D implements IVisualShape {
setFaceState();
setEdgeState();
} else if (index !== undefined) {
if (type === ShapeType.Face) {
if (ShapeType.hasEdge(type)) {
setFaceState();
} else if (type === ShapeType.Edge && this._edges) {
}
if (ShapeType.hasEdge(type) && this._edges) {
setEdgeState();
}
}
Expand Down
Loading

0 comments on commit 952e2cd

Please sign in to comment.