Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Color Customization for JupyterCAD Models #397

Merged
merged 32 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1e10ef0
caught (but remains only in start)
arjxn-py Aug 17, 2024
11d9f9e
Define color property in box schema
arjxn-py Sep 2, 2024
4a3b225
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 2, 2024
0292be7
Merge branch 'main' into custom-color
arjxn-py Sep 2, 2024
809e462
Merge branch 'main' into custom-color
arjxn-py Sep 2, 2024
9f1e47f
Fetch Color property from schema and use that to `buildShape` (Color …
arjxn-py Sep 3, 2024
c52c350
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 3, 2024
153bbd5
More tries to bring custom color to the model
arjxn-py Sep 4, 2024
a445b33
Able to set custom color of the mesh :tada:
arjxn-py Sep 4, 2024
f298f5f
Prevent going back to default color
arjxn-py Sep 4, 2024
ec82b63
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 4, 2024
bd761d1
Done :partying_face:
arjxn-py Sep 4, 2024
cfbdd0e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 4, 2024
4fa2360
Merge branch 'main' into custom-color
arjxn-py Sep 4, 2024
0c2b1d8
Color picker for changing color
arjxn-py Sep 4, 2024
0994d5d
Add color property to other shapes
arjxn-py Sep 4, 2024
27e5380
Add color property to more schemas [TO BE CONTINUED...]
arjxn-py Sep 5, 2024
3eca136
Almost covered
arjxn-py Sep 5, 2024
04fa303
Color logic handled for `cut`
arjxn-py Sep 6, 2024
b678b77
Handle Color for `union`, `intersection` & `extrusion`
arjxn-py Sep 6, 2024
9db3c4a
Add color handling for `fillet` & `chamfer`
arjxn-py Sep 6, 2024
3396d84
Define `_handleColorChange` inline
arjxn-py Sep 6, 2024
3081c44
Update Playwright Snapshots
github-actions[bot] Sep 6, 2024
ef135e4
apply object color only to non-selected mesh
arjxn-py Sep 6, 2024
cb2a07a
if not baseColor then `DEFAULT_MESH_COLOR`
arjxn-py Sep 6, 2024
40f782e
Merge branch 'main' into custom-color
arjxn-py Sep 6, 2024
1354dd0
Update Playwright Snapshots
github-actions[bot] Sep 6, 2024
9ffcf3e
Merge branch 'main' into custom-color
arjxn-py Sep 6, 2024
d952a76
Remove repeated code
arjxn-py Sep 9, 2024
6213c11
Save `userData.originalColor` in any case
arjxn-py Sep 9, 2024
780a8bc
Save objColor as original color
arjxn-py Sep 9, 2024
410518c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions packages/base/src/3dview/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,21 @@ export function buildShape(options: {
selected: boolean;
isSolid: boolean;
guidata?: IDict;
objColor?: THREE.Color | string | number;
arjxn-py marked this conversation as resolved.
Show resolved Hide resolved
}): {
meshGroup: THREE.Group;
mainMesh: THREE.Mesh<THREE.BufferGeometry, THREE.MeshPhongMaterial>;
edgesMeshes: LineSegments2[];
} | null {
const { objName, data, guidata, isSolid, clippingPlanes, selected } = options;
const {
objName,
data,
guidata,
isSolid,
clippingPlanes,
selected,
objColor
} = options;
const { faceList, edgeList, jcObject } = data;

const vertices: Array<number> = [];
Expand Down Expand Up @@ -148,14 +157,13 @@ export function buildShape(options: {
vInd += vertexCoorLength / 3;
}

let color = DEFAULT_MESH_COLOR;
let color = objColor || DEFAULT_MESH_COLOR;
let visible = jcObject.visible;
if (guidata && guidata[objName]) {
const objdata = guidata[objName];

if (Object.prototype.hasOwnProperty.call(objdata, 'color')) {
const rgba = objdata['color'] as number[];
color = new THREE.Color(rgba[0], rgba[1], rgba[2]);
color = new THREE.Color(color);
}

if (Object.prototype.hasOwnProperty.call(objdata, 'visibility')) {
Expand All @@ -168,7 +176,7 @@ export function buildShape(options: {
// We need one material per-mesh because we will set the uniform color independently later
// it's too bad Three.js does not easily allow setting uniforms independently per-mesh
const material = new THREE.MeshPhongMaterial({
color,
color: new THREE.Color(color),
wireframe: false,
flatShading: false,
clippingPlanes,
Expand Down
38 changes: 25 additions & 13 deletions packages/base/src/3dview/mainview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ export class MainView extends React.Component<IProps, IStates> {
Object.entries(payload).forEach(([objName, data]) => {
const selected = selectedNames.includes(objName);
const obj = this._model.sharedModel.getObjectByName(objName);
const objColor = obj?.parameters?.Color;

// TODO Have a more generic way to spot non-solid objects
const isSolid = !(
Expand All @@ -602,7 +603,8 @@ export class MainView extends React.Component<IProps, IStates> {
clippingPlanes: this._clippingPlanes,
selected,
isSolid,
guidata
guidata,
objColor
});

if (output) {
Expand All @@ -619,6 +621,14 @@ export class MainView extends React.Component<IProps, IStates> {
this._selectedMeshes.push(el as any as BasicMesh);
el.material.color = SELECTED_MESH_COLOR;
el.material.linewidth = SELECTED_LINEWIDTH;
el.userData.originalColor = new THREE.Color(objColor);
} else {
// Apply objColor for non-selected meshes
if (objColor && el.material?.color) {
const newColor = new THREE.Color(objColor);
el.material.color = newColor;
el.userData.originalColor = newColor.clone();
arjxn-py marked this conversation as resolved.
Show resolved Hide resolved
}
}
});
this._meshGroup?.add(meshGroup);
Expand Down Expand Up @@ -842,17 +852,12 @@ export class MainView extends React.Component<IProps, IStates> {
private _updateSelected(selection: { [key: string]: ISelection }) {
// Reset original color for old selection
for (const selectedMesh of this._selectedMeshes) {
let originalColor = selectedMesh.name.startsWith('edge-')
? DEFAULT_EDGE_COLOR
: DEFAULT_MESH_COLOR;
const guidata = this._model.sharedModel.getOption('guidata');
if (
guidata &&
guidata[selectedMesh.name] &&
guidata[selectedMesh.name]['color']
) {
const rgba = guidata[selectedMesh.name]['color'] as number[];
originalColor = new THREE.Color(rgba[0], rgba[1], rgba[2]);
let originalColor = selectedMesh.userData.originalColor;

if (!originalColor) {
originalColor = selectedMesh.name.startsWith('edge-')
? DEFAULT_EDGE_COLOR
: DEFAULT_MESH_COLOR;
}
if (selectedMesh.material?.color) {
selectedMesh.material.color = originalColor;
Expand All @@ -875,6 +880,12 @@ export class MainView extends React.Component<IProps, IStates> {
continue;
}

// Prevents object from going back to DEFAULT_MESH_COLOR
if (!selectedMesh.userData.originalColor) {
selectedMesh.userData.originalColor =
selectedMesh.material.color.clone();
}

this._selectedMeshes.push(selectedMesh);
if (selectedMesh?.material?.color) {
selectedMesh.material.color = SELECTED_MESH_COLOR;
Expand Down Expand Up @@ -1041,6 +1052,7 @@ export class MainView extends React.Component<IProps, IStates> {
const obj = this._meshGroup?.getObjectByName(objName) as
| BasicMesh
| undefined;
const objColor = obj?.material.color;
if (!obj) {
continue;
}
Expand All @@ -1064,7 +1076,7 @@ export class MainView extends React.Component<IProps, IStates> {
const color = new THREE.Color(rgba[0], rgba[1], rgba[2]);
obj.material.color = color;
} else {
obj.material.color = DEFAULT_MESH_COLOR;
obj.material.color = objColor || DEFAULT_MESH_COLOR;
}
}
}
Expand Down
31 changes: 25 additions & 6 deletions packages/base/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
wireframeIcon
} from './tools';
import keybindings from './keybindings.json';
import { DEFAULT_MESH_COLOR } from './3dview/helpers';
import { JupyterCadPanel, JupyterCadWidget } from './widget';
import { DocumentRegistry } from '@jupyterlab/docregistry';
import { PathExt } from '@jupyterlab/coreutils';
Expand Down Expand Up @@ -257,11 +258,14 @@ const OPERATORS = {
const selected = model.localState?.selected.value || {};
const sel0 = getSelectedMeshName(selected, 0);
const sel1 = getSelectedMeshName(selected, 1);
const baseName = sel0 || objects[0].name || '';
const baseModel = model.sharedModel.getObjectByName(baseName);
return {
Name: newName('Cut', model),
Base: sel0 || objects[0].name || '',
Base: baseName,
Tool: sel1 || objects[1].name || '',
Refine: false,
Color: baseModel?.parameters?.Color || DEFAULT_MESH_COLOR,
Placement: { Position: [0, 0, 0], Axis: [0, 0, 1], Angle: 0 }
};
},
Expand Down Expand Up @@ -297,13 +301,16 @@ const OPERATORS = {
const objects = model.getAllObject();
const selected = model.localState?.selected.value || {};
const sel0 = getSelectedMeshName(selected, 0);
const baseName = sel0 || objects[0].name || '';
const baseModel = model.sharedModel.getObjectByName(baseName);
return {
Name: newName('Extrusion', model),
Base: sel0 || objects[0].name || '',
Base: baseName,
Dir: [0, 0, 1],
LengthFwd: 10,
LengthRev: 0,
Solid: false,
Color: baseModel?.parameters?.Color || DEFAULT_MESH_COLOR,
Placement: { Position: [0, 0, 0], Axis: [0, 0, 1], Angle: 0 }
};
},
Expand Down Expand Up @@ -339,10 +346,13 @@ const OPERATORS = {
const selected = model.localState?.selected.value || {};
const sel0 = getSelectedMeshName(selected, 0);
const sel1 = getSelectedMeshName(selected, 1);
const baseName = sel0 || objects[0].name || '';
const baseModel = model.sharedModel.getObjectByName(baseName);
return {
Name: newName('Union', model),
Shapes: [sel0 || objects[0].name || '', sel1 || objects[1].name || ''],
Shapes: [baseName, sel1 || objects[1].name || ''],
Refine: false,
Color: baseModel?.parameters?.Color || DEFAULT_MESH_COLOR,
Placement: { Position: [0, 0, 0], Axis: [0, 0, 1], Angle: 0 }
};
},
Expand Down Expand Up @@ -380,10 +390,13 @@ const OPERATORS = {
const selected = model.localState?.selected.value || {};
const sel0 = getSelectedMeshName(selected, 0);
const sel1 = getSelectedMeshName(selected, 1);
const baseName = sel0 || objects[0].name || '';
const baseModel = model.sharedModel.getObjectByName(baseName);
return {
Name: newName('Intersection', model),
Shapes: [sel0 || objects[0].name || '', sel1 || objects[1].name || ''],
Shapes: [baseName, sel1 || objects[1].name || ''],
Refine: false,
Color: baseModel?.parameters?.Color || DEFAULT_MESH_COLOR,
Placement: { Position: [0, 0, 0], Axis: [0, 0, 1], Angle: 0 }
};
},
Expand Down Expand Up @@ -419,11 +432,14 @@ const OPERATORS = {
default: (model: IJupyterCadModel) => {
const objects = model.getAllObject();
const selectedEdge = getSelectedEdge(model.localState?.selected.value);
const baseName = selectedEdge?.shape || objects[0].name || '';
const baseModel = model.sharedModel.getObjectByName(baseName);
return {
Name: newName('Chamfer', model),
Base: selectedEdge?.shape || objects[0].name || '',
Base: baseName,
Edge: selectedEdge?.edgeIndex || 0,
Dist: 0.2,
Color: baseModel?.parameters?.Color || DEFAULT_MESH_COLOR,
Placement: { Position: [0, 0, 0], Axis: [0, 0, 1], Angle: 0 }
};
},
Expand Down Expand Up @@ -457,11 +473,14 @@ const OPERATORS = {
default: (model: IJupyterCadModel) => {
const objects = model.getAllObject();
const selectedEdge = getSelectedEdge(model.localState?.selected.value);
const baseName = selectedEdge?.shape || objects[0].name || '';
const baseModel = model.sharedModel.getObjectByName(baseName);
return {
Name: newName('Fillet', model),
Base: selectedEdge?.shape || objects[0].name || '',
Base: baseName,
Edge: selectedEdge?.edgeIndex || 0,
Radius: 0.2,
Color: baseModel?.parameters?.Color || DEFAULT_MESH_COLOR,
Placement: { Position: [0, 0, 0], Axis: [0, 0, 1], Angle: 0 }
};
},
Expand Down
3 changes: 3 additions & 0 deletions packages/base/src/panelview/formbuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ export class ObjectPropertiesForm extends React.Component<IProps, IStates> {
uiSchema[k] = {};
this.removeArrayButton(v, uiSchema[k]);
}
uiSchema['Color'] = {
'ui:widget': 'color'
};
});
}

Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/any.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
"type": "string",
"enum": ["brep", "step", "stl"]
},
"Color": {
"type": "string",
"description": "The color of the object",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/box.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
"exclusiveMinimum": 0,
"description": "The height of the box"
},
"Color": {
"type": "string",
"description": "The color of the box",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/chamfer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"minimum": 0,
"description": "The distance of the symmetric chamfer"
},
"Color": {
"type": "string",
"description": "The color of the chamfer",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/cone.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
"exclusiveMinimum": 0,
"description": "The angle of the cone"
},
"Color": {
"type": "string",
"description": "The color of the cone",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/cut.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"type": "boolean",
"description": "Refine shape"
},
"Color": {
"type": "string",
"description": "The color of the cut object",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/cylinder.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
"exclusiveMinimum": 0,
"description": "Angle of the cylinder"
},
"Color": {
"type": "string",
"description": "The color of the cylinder",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/extrusion.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
"type": "boolean",
"description": "If true, creating a solid"
},
"Color": {
"type": "string",
"description": "The color of the extrusion",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/fillet.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"exclusiveMinimum": 0,
"description": "The radius for the fillet"
},
"Color": {
"type": "string",
"description": "The color of the fillet",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/fuse.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"type": "boolean",
"description": "Refine shape"
},
"Color": {
"type": "string",
"description": "The color of the fused object",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/intersection.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"type": "boolean",
"description": "Refine shape"
},
"Color": {
"type": "string",
"description": "The color of the intersection",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/sketch.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
]
}
},
"Color": {
"type": "string",
"description": "The color of the sketch object",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/schema/src/schema/sphere.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
"type": "number",
"description": "The angle of the sphere"
},
"Color": {
"type": "string",
"description": "The color of the sphere",
"default": "#808080"
},
"Placement": {
"$ref": "./placement.json"
}
Expand Down
Loading
Loading