-
Notifications
You must be signed in to change notification settings - Fork 5
Scratchpad Sink Source
One main problem: sources and sinks have their own order of processing. E.g. a PLY file needs to write all vertices with properties first, then all faces with properties. An STL file writes all faces with vertices in one go. OBJ first writes all values of vertex property 1, then vertex property 2 and so on. So we have widely different data layouts. Similarly for the source: reading different file formats makes data available in a different order. Non-file sources, like shapes or ISO surfaces, also have their own algorithms which generate the mesh in a specific order.
In contrast to that are random access data structures where mesh data (including properties) can be accessed or created in any order (except for simple rules like "you have to create a face before adding properties to it"). These structures are completely in memory.
As a consequence, it's almost impossible (at all) to transfer from a source to a sink with only constant memory requirements. If the order of data processing is the same for source and sink, it's possible. But since this is rare (there are many different ways to process the data), it doesn't make sense to hope for that as a general solution. (It might be worthwhile adding a system to allow this streaming transfer; but it is low priority.) Thus, we need a temporary storage for transfers in general.
- Mesh: Which type?
- Positions:
- yes/no?
- Normals
- yes/no?
- Merge/unify vertices?
- Mesh: Which type?
- Per property:
- Yes/no?
- Mesh: Which type?
- Per property:
- Yes/no?
-
MeshSource
- potentially information about prop type, potentially not
-
MeshSink
- Can have requirements (e.g. "need positions!")
- Either very fixed requirements and additional fields ignored
- Or no requirements and all fields are just used as provided (files)
- Or in between
- Can have requirements (e.g. "need positions!")
-
Two possibilities for
PropSet
:- visitor based (basically a
visit(self, impl Visitor)
method) - Poll based (methods like
position()
, ...)
- visitor based (basically a
What we want:
- Create OpenGL Buffer directly from file
- Create OpenGL buffer from a shape description
Sources:
- Files
- Shape descriptions
Sinks:
- OpenGL Buffer
Files
// ========================================================================
trait MeshSource {
type VertexInfo;
type FaceInfo;
fn build(self, sink: &mut impl MeshSink<Self::VertexInfo, Self::FaceInfo>);
}
trait MeshSink<VertexInfoT, FaceInfoT> {
fn add_vertex(&mut self, info: VertexInfoT) -> VertexHandle;
fn add_face(&mut self, info: FaceInfoT) -> FaceHandle;
}
// ========================================================================
trait MeshSource {
type VertexInfo: PropSet;
type FaceInfo: PropSet;
fn build(self, sink: &mut impl MeshSink<Self::VertexInfo, Self::FaceInfo>);
}
trait MeshSink<VertexInfoT, FaceInfoT> {
fn add_vertex(&mut self, info: VertexInfoT) -> Result<VertexHandle, _>;
fn add_face(&mut self, info: FaceInfoT) -> Result<FaceHandle, _>;
}
trait PropSet {
fn visit(self, visitor: &mut impl PropVisitor);
}
trait PropVisitor {
fn visit_position(&mut self, )
fn visit_normal(&mut self)
}
// ========================================================================
impl<VertexInfoT, FaceInfoT> MeshSink<VertexInfoT, FaceInfoT> for PlyWriter
where
VertexInfoT: HasPosition<Scalar = f32>, // or via `Into<f32>`
{
if FaceInfoT::HAS_NORMAL {
}
}
build! {
type: SharedVertexMesh,
vertex_maps: [
positions: |info| info.position,
colors: |_| 3,
],
face_maps: [
normals: |info| info.normal,
],
}
Disadvantages:
- New, surprising syntax
Advantages:
- only specified what's necessary
- could do error checking maybe?
let positions = VecMap::empty();
let normals = VecMap::empty();
let mesh = my_disc.build::<SharedVertexMesh>()
.add_vertex_prop(&mut positions, |info| info.position)
.add_face_prop(&mut normals, |info| info.normal);
Disadvantages:
- Map type specified while unimportant/redundant (or is it?)
- API assumes maps are empty but no way to express that except for docs
Advantages:
- Standard Rust syntax