logic transfer

master
mitchellhansen 9 months ago
parent 699affa625
commit c642974997

@ -0,0 +1,220 @@
#[derive(Component)]
struct FjSolidWrapper{
handle: fj_core::storage::Handle<Solid>,
}
#[derive(Component)]
struct FjConvertedFlag;
use fj_core::{
algorithms::sweep::Sweep,
objects::{Region, Sketch, Solid},
operations::{BuildRegion, BuildSketch, Insert, UpdateSketch},
services::Services,
storage::Handle,
};
use fj_core::algorithms::approx::Tolerance;
use fj_core::algorithms::bounding_volume::BoundingVolume;
use fj_core::algorithms::triangulate::Triangulate;
use fj_core::objects::{Cycle, Shell};
use fj_core::operations::{BuildCycle, Reverse, UpdateRegion};
use fj_interop::mesh::Mesh;
use fj_math::{Aabb, Point, Scalar, Vector};
use std::ops::Deref;
use bevy::prelude::Mesh;
use bevy::render::mesh::{Indices, PrimitiveTopology};
use fj_interop::mesh::Mesh as FjMesh;
use fj_math::Point;
fn generate_uv_mapping(fj_mesh: &FjMesh<Point<3>>) -> Vec<[f32; 2]> {
let mut uvs = Vec::new();
for vertex in fj_mesh.vertices() {
let x = vertex.coords.x.into_f32();
let y = vertex.coords.y.into_f32();
// Here we're using x and y coordinates as u and v
uvs.push([x, y]);
uvs.push([x, y]);
uvs.push([x, y]);
uvs.push([x, y]);
uvs.push([x, y]);
uvs.push([x, y]);
}
uvs
}
fn generate_normals(fj_mesh: &FjMesh<Point<3>>) -> Vec<[f32; 3]> {
let mut normals = Vec::new();
for triangle in fj_mesh.triangles() {
let normal = triangle.inner.normal();
normals.push([normal.x.into_f32(), normal.y.into_f32(), normal.z.into_f32()]);
normals.push([normal.x.into_f32(), normal.y.into_f32(), normal.z.into_f32()]);
normals.push([normal.x.into_f32(), normal.y.into_f32(), normal.z.into_f32()]);
}
normals
}
fn generate_positions(fj_mesh: &FjMesh<Point<3>>) -> Vec<[f32; 3]> {
let mut positions = Vec::new();
// Iterate through each triangle
for triangle in fj_mesh.triangles() {
// For each vertex index in the triangle
for vertex_index in triangle.inner.points() {
positions.push([vertex_index.x.into_f32(), vertex_index.y.into_f32(), vertex_index.z.into_f32()]);
}
}
positions
}
fn generate_indices(fj_mesh: &FjMesh<Point<3>>) -> Vec<u32> {
let mut num_positions = 0;
// Count the total number of positions (3 per triangle)
for triangle in fj_mesh.triangles() {
num_positions += 3;
}
// Generate the indices [0, 1, 2, ..., num_positions-1]
(0..num_positions as u32).collect()
}
// Need to take a solid, and return all the data needed to create a Bevy Mesh from scratch
pub fn convert_mesh(fj_mesh: &FjMesh<Point<3>>) -> Mesh {
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, generate_positions(&fj_mesh));
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, generate_normals(&fj_mesh));
// mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, generate_uv_mapping(&fj_mesh));
mesh.set_indices(Some(Indices::U32(generate_indices(&fj_mesh))));
mesh
}
fn model(x: f64, y: f64, z: f64, services: &mut Services) -> Handle<Solid> {
let sketch = Sketch::empty()
.add_region(
Region::polygon(
[
[-x / 2., -y / 2.],
[x / 2., -y / 2.],
[x / 2., y / 2.],
[-x / 2., y / 2.],
],
services,
)
.add_interiors(
[
Cycle::polygon(
[
[0.1, 0.1],
[0.1, 2.0],
[2.0, 2.0],
[2.0, 0.1],
],
services,
).insert(services),
// Cycle::circle([0.1,0.75], 0.05, services).reverse(services).insert(services),
// MinnesotaCycle::circle([0.1,0.75], 0.05, services).reverse(services).insert(services)
]
)
.insert(services),
)
// .add_region(
// Region::polygon(
// [
// [1.5, 2.25],
// [3.0, 2.25],
// [3.0, 4.5],
// [1.5, 4.5],
// ],
// services,
// ).insert(services)
// )
.insert(services);
let surface = services.objects.surfaces.xy_plane();
let path = Vector::from([0., 0., z]);
// let mut iter = sketch.faces(surface, services).into_iter();
// let face = iter.next().unwrap();
// let face = iter.next().unwrap();
// services.drop_and_validate();
// face.sweep(path, services)
// let surface = services.objects.surfaces.xy_plane();
(sketch, surface).sweep(path, services)
}
pub fn build_mesh() -> (Mesh<Point<3>>, Handle<Solid>) {
let mut services = Services::new();
let model = model(4., 8., (1.0 / 12.0 * 0.75), &mut services);
let aabb = model.aabb().unwrap_or(Aabb {
min: Point::origin(),
max: Point::origin(),
});
println!("{:?}", model);
let mut min_extent = Scalar::MAX;
for extent in aabb.size().components {
if extent > Scalar::ZERO && extent < min_extent {
min_extent = extent;
}
}
let tolerance = min_extent / Scalar::from_f64(1000.);
let tolerance = Tolerance::from_scalar(tolerance).unwrap();
((model.deref(), tolerance).triangulate(), model)
}
fn update_fj_model_system(
mut commands: Commands,
query: Query<(Entity, &FjSolidWrapper), Without<FjConvertedFlag>>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
for (entity, solid) in &query {
let (mesh, fj_model) = fornjot_stuff::build_mesh();
let bevy_mesh = fornjot_convert_mesh::convert_mesh(&mesh);
commands.entity(entity).insert(
(
PbrBundle {
mesh: meshes.add(Mesh::from(bevy_mesh.clone())),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.0, 0.0),
..default()
},
FjMeshWrapper { data: mesh, data2: fj_model },
FjConvertedFlag
));
}
}
pub struct FjRenderPlugin;
impl Plugin for FjRenderPlugin {
fn build(&self, app: &mut App) {
app
.add_systems(Update, update_fj_model_system);
}
}
Loading…
Cancel
Save