Nodi Modular
Quickstart
Modular is a module project designed to import node graphs created in Nodi in JSON format, enabling the extraction of geometric data generated based on the node graph structure.
Prepare Project
Place .json file exported from app.nodi3d.com
Install
nodi-modular is available via npm:
Copy
Ask AI
npm install nodi-modular
Features can now be imported via "nodi-modular"
Copy
Ask AI
import init, { Modular } from "nodi-modular";
Usage
Copy
Ask AI
import init, { Modular } from "nodi-modular";
// Initialize the WebAssembly module
await init();
// Create a new instance of the Modular
const modular = Modular.new();
// Load a node graph in JSON format as a string
modular.loadGraph(JSON.stringify({
nodes: { ... },
}));
// Evaluate the node graph to get the result
const result = modular.evaluate();
// Geometry identifiers are the keys of the geometries in the result
const { geometryIdentifiers } = result;
geometryIdentifiers.forEach((identifier) => {
// Get the geometry variant by identifier
// variants are curve, surface, mesh, and etc.
const geometry = modular.findGeometryById(identifier);
// Get the geometry interop by identifier
// geometry interop has the data that can be rendered as a polygonalized data (polyline or triangle mesh)
const interop = modular.findGeometryInteropById(identifier);
});
// Get the nodes of the node graph
const nodes = modular.getNodes();
// Find the node by the variant and label
const numberOfGrid = nodes.find((n) => n.variant === "Number" && n.label === 'number of grid');
// Each nodes have the properties that can be changed
// What properties can be changed depends on the node variant, so you need to check the node variant's properties (numberGrid["properties"])
modular.changeNodeProperty(numberOfGrid.id, {
name: "value",
value: {
type: "Number",
content: 30,
}
});
// re-evaluate the node graph to get the result after the property change
const resultAfterPropertyChange = await modular.evaluate();
Copy
Ask AI
import init, { Modular } from "nodi-modular";
// Initialize the WebAssembly module
await init();
// Create a new instance of the Modular
const modular = Modular.new();
// Load a node graph in JSON format as a string
modular.loadGraph(JSON.stringify({
nodes: { ... },
}));
// Evaluate the node graph to get the result
const result = modular.evaluate();
// Geometry identifiers are the keys of the geometries in the result
const { geometryIdentifiers } = result;
geometryIdentifiers.forEach((identifier) => {
// Get the geometry variant by identifier
// variants are curve, surface, mesh, and etc.
const geometry = modular.findGeometryById(identifier);
// Get the geometry interop by identifier
// geometry interop has the data that can be rendered as a polygonalized data (polyline or triangle mesh)
const interop = modular.findGeometryInteropById(identifier);
});
// Get the nodes of the node graph
const nodes = modular.getNodes();
// Find the node by the variant and label
const numberOfGrid = nodes.find((n) => n.variant === "Number" && n.label === 'number of grid');
// Each nodes have the properties that can be changed
// What properties can be changed depends on the node variant, so you need to check the node variant's properties (numberGrid["properties"])
modular.changeNodeProperty(numberOfGrid.id, {
name: "value",
value: {
type: "Number",
content: 30,
}
});
// re-evaluate the node graph to get the result after the property change
const resultAfterPropertyChange = await modular.evaluate();
Copy
Ask AI
import init, { Modular } from "nodi-modular";
.
.
.
const [modular, setModular] = useState<Modular | null>(null);
const [nodes, setNodes] = useState<NodeInterop[]>([]);
const [geometries, setGeometries] = useState<BufferGeometry[]>([]);
const evaluate = useCallback(
(m: Modular) => {
m.evaluate().then((e) => {
const { geometryIdentifiers } = e;
const gs = geometryIdentifiers
.map((id) => {
const interop = m.findGeometryInteropById(id);
const { transform } = id;
switch (interop?.variant) {
case "Mesh": {
const { data } = interop;
const geometry = new BufferGeometry();
const { vertices, normals, faces } = data;
geometry.setAttribute(
"position",
new BufferAttribute(new Float32Array(vertices.flat(1)), 3)
);
geometry.setAttribute(
"normal",
new BufferAttribute(new Float32Array(normals.flat(1)), 3)
);
if (faces !== undefined) {
geometry.setIndex(
new BufferAttribute(new Uint32Array(faces.flat(1)), 1)
);
}
geometry.applyMatrix4(new Matrix4().fromArray(transform));
return geometry;
}
default: {
return null;
}
}
})
.filter((g): g is BufferGeometry => g !== null);
setGeometries(gs);
});
},
[]
);
.
.
.
useEffect(() => {
(async () => {
await init();
setModular(Modular.new());
})();
}, []);
useEffect(() => {
if (modular !== null) {
modular.loadGraph(JSON.stringify(shell.graph));
// modular.loadGraph(JSON.stringify(brickWall.graph));
const nodes = modular.getNodes();
const numberNodes = nodes.filter((n) => n.variant === "Number" || n.variant === "NumberSlider");
setNodes(numberNodes);
evaluate(modular);
}
}, [modular, evaluate]);
On this page
Assistant
Responses are generated using AI and may contain mistakes.