[x3d-public] InlineGeometry node and PLY format support in Castle Game Engine
Michalis Kamburelis
michalis at castle-engine.io
Fri Apr 17 18:50:23 PDT 2026
I implemented "InlineGeometry.smooth" in Castle Model Viewer! :)
Note that it is only applied if the underlying mesh _does not have already explicit normal vectors_. Just like "creaseAngle".
Our docs in CGE make it clear: "If the mesh does not provide explicit normal vectors, this field specifies whether the normals should be generated as smooth (per-vertex) or flat (per-face)."
Exact algorithm is visible on https://github.com/castle-engine/castle-engine/blob/31c90e3c4ef83659d91345c1e28384b062a1c0d0/src/scene/x3d/x3dnodes_standard_networking.inc#L824 . In short:
- If the underlying geometry has "creaseAngle" (like IndexedFaceSet) then this forces creaseAngle -> 0 (smooth=FALSE) or 4 (smooth=TRUE).
- Note: for our engine, any creaseAngle value >= pi is allowed and perfectly smooth, and we use 4 by convention to not worry about epsilons at comparisons.
- Otherwise, if the underlying geometry has only "normalPerVertex" (like X3DComposedGeometryNode, which is ancestor for many nodes, and determines normal generation for IndexedTriangleSet), and it has normal=NULL (because we only want to change generation of normals, not interpretation of user-provided normals) then we do "normalPerVertex:=smooth".
Note: I would suggest to make "smooth" more flexible, by making it enum, not boolean:
SFString [in,out] smooth "DEFAULT" ["DEFAULT", "FLAT", "SMOOTH"]
Then the "DEFAULT" would mean "use whatever normals have been provided, or automatic normals generated with convention implied by the model format". And values "FLAT", "SMOOTH" would override it (also overriding normals provided in the model, if any). So we have better behavior + more possibilities:
- the authors would get possibility to override normals (even if provided by the model -- some models provide wrong normals),
- but at the same time, authors could let the underlying geometry dictate things, letting smooth=DEFAULT.
- In contrast, the current boolean approach means that if you use InlineGeometry to import IndexedFaceSet from X3D -> then original "IndexedFaceSet.creaseAngle" doesn't matter (since "smooth" has to override it) which is a pity in case author set reasonable "IndexedFaceSet.creaseAngle".
Anyhow, I realize that most often use-case for InlineGeometry is including PLY / STL models, that have no sophisticated way to influence normal generation (like creaseAngle), so new "smooth" parameter gives good control to authors.
Note: The "smooth" field in current implementation doesn't work for STL, for reasons probably uninteresting here (the STL importer overrides normals with flat always now) -- it's a TODO to fix it. For now, it behaves as it should for all other formats, including PLY, X3D, glTF...
This will be soon available in snapshots on https://castle-engine.io/castle-model-viewer , once it passes automatic tests. Our demo models contain tests for it ( https://github.com/castle-engine/demo-models/tree/master/ply , https://github.com/castle-engine/demo-models/tree/master/x3d/inline_geometry ).
Regards,
Michalis
On Thursday, April 16th, 2026 at 21:31, Don Brutzman <don.brutzman at gmail.com> wrote:
> Thanks for prior discussions on smooth/sharp rendering and evaluation of creaseAngle suitability. Simplest resolution seems to be adding a SFBool smooth field as a hint.
>
> Image follows showing that authors also need to control single-sided versus double-sided rendering, which can be accomplished as usual using the solid field. Sometimes you want it, sometimes you don't. This screenshot illustrates how single-sided rendering lets a user look through the inside of a teapot's body and spout.
>
> - [X3D4AM, X3D for Advanced Modeling Examples Archive, Additive Manufacturing, Teapot Inline Geometry Ply](https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlyIndex.html)
> - Loading a classic teapot model in PLY format
> - https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlyIndex.html
>
> [image.png]
>
> I don't think we need to worry about ccw or convex fields... that is best left to the X3D player implementing this node. The mesh "is what it is" and an author is choosing not to do conversions when they use InlineGeometry node.
>
> Additional thanks for review by X3D Ecology working group this week, also another review session with Dick Puk. Refined specification prose follows. Once again, all comments welcome.
>
> - X3D Architecture v4.1 draft, clause 9 Networking component, [9.4.3 InlineGeometry](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/components/networking.html#InlineGeometry)
> - https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/components/networking.html#InlineGeometry
>
> 9.4.3 InlineGeometry
>
> InlineGeometry : X3DGeometryNode, X3DUrlObject {
> SFTime [in,out] autoRefresh 0.0 [0,infinity)
> SFTime [in,out] autoRefreshTimeLimit 3600.0 [0,infinity)
> SFString [in,out] description ""
> SFBool [in,out] load TRUE
> SFNode [in,out] metadata NULL [X3DMetadataObject]
> SFBool [in,out] solid FALSE
>
> SFBool [in,out] smooth TRUE
>
> MFString [in,out] url [] [URI]
> }
>
> InlineGeometry loads geometry from an external file. The result provides a polygonal mesh, set of lines, point cloud, parametric surface, or other geometry.
>
> The smooth field provides a hint to the browser whether smooth rendering is preferred for a retrieved polygonal mesh.
>
> The solid field is described in [11.2.3 Common geometry fields](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/components/rendering.html#CommonGeometryFields). For InlineGeometry, the default value of solid is FALSE since most usages of retrieved meshes need two-sided rendering. Authors have the option to change this value for single-sided rendering.
>
> The url field can support loading a variety of file formats defining polygonal mesh geometry. When the url field contains no values ([]), no default geometry is provided. Required support by X3D browsers includes both ASCII and binary encodings for the STL format (see [STL](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/bibliography.html#STL)) as well as the PLY polygonal geometry format (see [PLY](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/bibliography.html#PLY)), respectively. Other file types can be optionally supported by a browser.
>
> If the url field refers to an X3D file or a VRML97 file, the first geometry node found in that file (excluding both prototype declarations and prototype instances) is used to provide the InlineGeometry contents. X3D browsers shall recognize url fields that end with "#DEFname" to mean the geometry node with DEF label of DEFname in the given X3D or VRML97 file.
>
> The run-time system can support any number of 3D model resource types as long as those follow the available Model Primary Content Type for Multipurpose Internet Mail Extensions (MIME) model definition (see [RFC2077](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/references.html#RFC2077)), provide a registered content type (e.g., model/stl, text/plain etc.) (see [IANA_MEDIA](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/references.html#IANA_MEDIA) and [IANA_STL](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/references.html#IANA_STL)), and can be determined with some form of content negotiation (see [RFC9110](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/references.html#RFC9110)). Support is recommended for both text and binary encodings associated with a given model format, when so defined.
>
> EXAMPLES
>
> Shape {
> geometry InlineGeometry { url [ "MyFavoriteMesh.stl" ] }
>
> appearance USE FancyPaintAppearance # previously defined
> }
>
> Shape {
> geometry InlineGeometry { url [ "HelloWorld.x3d#TextMessage" ] }
>
> appearance USE FancyPaintAppearance # previously defined
> }
>
> NOTE Experimental variations of PLY format used for Gaussian Splat rendering are not expected for InlineGeometry. Such capabilities are better supported by Inline node loading of glTF models.
>
> Editors notes.
>
> - InlineGeometry results differ from an Inline node, which produces an X3DChildNode scene subgraph implementing the X3DBoundedObject interface. An Inline node cannot be used as the geometry field of a Shape.
> - Results from browser loading may be any kind of polygonal mesh or parametric surface as an X3DGeometryNode instance (e.g. IndexedFaceSet, TriangleSet, Extrusion, QuadSet etc.) but cannot be further manipulated or animated by events from the scene.
> - Direct loading of such geometry files eliminates the need for prior model conversion into X3D, and adds model flexibility when applying Appearance to the result.
> - Have listed "required support" of STL/PLY formats rather than "recommended support" since models described using these two formats are primary use cases, and numerous open-source conversion implementations are available.
> - Are better authoritative references possible for STL and PLY? See [Mantis 1522](https://mantis.web3d.org/view.php?id=1522).
> - The "#DEFname" syntax directly matches [EXTERNPROTO URL semantics](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/concepts.html#EXTERNPROTOURLSemantics) considerations. Not requiring IMPORT/EXPORT statements provides greater backwards compatibility with legacy models, avoiding unnecessary complications and possible ambiguity.
> - Composition of online addresses and parameter values within a url field offers the possibility of invoking an online server to perform file-format conversions. See email thread [[x3d-public] Inline > type field > for loading / converting / parsing other content](https://web3d.org/pipermail/x3d-public_web3d.org/2026-March/022355.html) for further discussion. Such additional functionality supports the use cases under consideration by Metaverse Standards Forum (MSF) [3D Web Interoperability](https://metaverse-standards.org/domain-groups/3d-web-interoperability) Working Group.
>
> Have fun with X3D extensibility! 😁
>
> all the best, Don
> --
> X3D Graphics, Maritime Robotics, Distributed Simulation
> Relative Motion Consulting https://RelativeMotion.info
>
> On Thu, Apr 9, 2026 at 7:11 PM Don Brutzman <don.brutzman at gmail.com> wrote:
>
>> Not a spec problem. Level 1 is written to provide options for Interchange profile, namely minimal support on minimal platforms.
>>
>> Thanks for checking Joe... Nothing we have to worry about here.
>>
>> all the best, Don
>> --
>> X3D Graphics, Maritime Robotics, Distributed Simulation
>> Relative Motion Consulting https://RelativeMotion.info
>>
>> On Thu, Apr 9, 2026 at 4:42 PM Joe D Williams <joedwil at earthlink.net> wrote:
>>
>>> OK, so IFS lists two versions of creaseAngle
>>>
>>> Table 13.2 — Geometry3D component support levels
>>> Level 2
>>> IndexedFaceSet
>>> Core 1
>>> Grouping 1
>>> Rendering 1
>>> Shape 1
>>> For creaseAngle, only 0 and π radians supported
>>>
>>> except:
>>>
>>> 13.3.6 IndexedFaceSet
>>> SFFloat [] creaseAngle 0 [0,∞)
>>>
>>> and,
>>>
>>> Table 11.2 — Rendering component support levels
>>> IndexedTriangleSet
>>> Level 3
>>> Core 1
>>> Grouping 1
>>> All fields fully supported.
>>> (No creaseAngle)
>>>
>>> OK, but IFS creaseAngle technically ends up 0 to pi whatever you put in there,
>>>
>>> but by experiment it seems to work in that range.
>>>
>>> and the note should be removed from 13.2 and moved to ITS?
>>>
>>> Thanks,
>>>
>>> Joe
>>>
>>> Table 13.2 — Geometry3D component support levels
>>> Level 2
>>> IndexedFaceSet
>>> Core 1
>>> Grouping 1
>>> Rendering 1
>>> Shape 1
>>> For creaseAngle, only 0 and π radians supported
>>>
>>> Table 11.2 — Rendering component support levels
>>> IndexedTriangleSet
>>> Level 3
>>> Core 1
>>> Grouping 1
>>>
>>> Is this a spec problem?
>>>
>>> I can be ok with ITS 0 or pi creaseAngle value
>>>
>>> but I thought IFS could 0 to pi.
>>>
>>> So use know that
>>>
>>> -----Original Message-----
>>> From: Don Brutzman <don.brutzman at gmail.com>
>>> Sent: Apr 9, 2026 3:33 PM
>>> To: Michalis Kamburelis <michalis at castle-engine.io>
>>> Cc: Extensible 3D \(X3D\) Graphics public discussion <x3d-public at web3d.org>, <joedwil at earthlink.net>
>>> Subject: Re: [x3d-public] InlineGeometry node and PLY format support in Castle Game Engine
>>>
>>> Good points all in this thread, lots to consider here as we strive for simple effectiveness.
>>>
>>> Any geometry type might be returned... if there was an <InlineGeometry url="MyExpensiveCadModel.x3d#QuadSetOfInterest"/> it seems likely a QuadSet would be returned.
>>>
>>> A creaseAngle field might lead to much downstream confusion, even if a satisfactory specification definition was crafted.
>>>
>>> A much-simpler possible field to express author intent: a 'smooth' field declaring a hint for applying smooth versus sharp shading, if possible.
>>>
>>> - SFBool [in out] smooth TRUE
>>>
>>> all the best, Don
>>> --
>>> X3D Graphics, Maritime Robotics, Distributed Simulation
>>> Relative Motion Consulting https://RelativeMotion.info
>>>
>>> On Thu, Apr 9, 2026 at 2:12 PM Michalis Kamburelis <michalis at castle-engine.io> wrote:
>>>
>>>> To Don's idea of "creaseAngle as a suggestion":
>>>>
>>>> I'm not against it (and I would support it in CGE as much as we could :) ). But as a hint, it could be problematic, as users will find it is not reliable and could have "wrong expectations".
>>>>
>>>> - E.g. X_ITE generates IndexedTriangleSet from PLY mesh, while CGE generates (right now!) IndexedFaceSet. This means that users could have wrong expectations from X_ITE -- creaseAngle, for PLY, in X_ITE would not work.
>>>>
>>>> - ( Unless X_ITE changes algorithm to use IndexedFaceSet. But forcing this would be bad -- a browser should have a choice what geometry type to use here, not be forced to use IndexedFaceSet . Which geometry type is more suitable -> depends on internal optimizations. )
>>>>
>>>> - If CGE changes our algorithm (which I reserve the right to do! we had in the past occasions when it made sense to change geometry types for terrains), then suddenly we will have bugreports "InlineGeometry.createAngle for PLY worked in Castle Model Viewer version 5, but no longer works in version 6". This will make users unhappy:) Explaining to users that "InlineGeometry.creaseAngle was always supposed to be only a hint, never guarantee" will not be of much help -- because users will then have models that depended on the old behavior, and will consider the new behavior a regression.
>>>>
>>>> Also: browsers should be "consistent by default" anyway. We should to "what is expected by given format". Which means that, if PLY models are (by convention) displayed with smooth normals (when no explicit normals are provided) -> then all viewers, X_ITE and CGE, should display them by default with smooth normals. (Which is what happens now, after my change yesterday:) ).
>>>>
>>>> IOW, I'm not against InlineGeometry.creaseAngle (as long as default would be "-1" meaning "no override")... but it doesn't achieve that much (we need to make our defaults consistent anyway), and may in fact give wrong expectations to users (when it will work only in certain browsers/versions).
>>>>
>>>> To Joe: I'm afraid making the geometry type depending on profile would be surprising to users, and would not really solve the issue discussed here :)
>>>>
>>>> Both browsers (X_ITE and CGE) support both geometry types (IndexedTriangleSet and IndexedFaceSet). It's not a question of support. Both browsers choose to load PLY as most optimal format, which may be a different decision for each browser. This should not be influenced by profile of enclosing file, this would be quite non-standard (as the profile also doesn't influence regular Inline).
>>>>
>>>> Regards,
>>>> Michalis
>>>> On Thursday, April 9th, 2026 at 03:09, Don Brutzman via x3d-public <x3d-public at web3d.org> wrote:
>>>>
>>>>> Please re-read my suggestions from earlier today. Apologies for not being clearer.
>>>>>
>>>>> I was trying to express that creaseAngle might be a hint from the author, regardless of original inlined geometry mesh type and also independent of the browsers choice of geometry (IFS, triangles, etc.). It is a way for author to express whether smooth rendering is desired.
>>>>>
>>>>> For example, a literal creaseAngle might be literally unusable if browser chooses to return a TriangleSet, but the browser might add Normal values to address smooth/sharp edges.
>>>>>
>>>>> all the best, Don
>>>>> --
>>>>> X3D Graphics, Maritime Robotics, Distributed Simulation
>>>>> Relative Motion Consulting https://RelativeMotion.info
>>>>>
>>>>> On Wed, Apr 8, 2026 at 5:30 PM Joe D Williams via x3d-public <x3d-public at web3d.org> wrote:
>>>>>
>>>>>> Choice of IFS or ITS could be a choice of Profile.
>>>>>>
>>>>>> IFS is simple profile, rendering 1 for IFS and rendering 3 for ITS.
>>>>>>
>>>>>> Joe
>>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Michalis Kamburelis via x3d-public <x3d-public at web3d.org>
>>>>>> Sent: Apr 8, 2026 1:17 PM
>>>>>> To: Holger Seelig <holger.seelig at yahoo.de>
>>>>>> Cc: Michalis Kamburelis <michalis at castle-engine.io>, Extensible 3D (X3D) Graphics public discussion <x3d-public at web3d.org>
>>>>>> Subject: Re: [x3d-public] InlineGeometry node and PLY format support in Castle Game Engine
>>>>>>
>>>>>> Hm, good point about the geometry type and so, the creaseAngle not being that much useful...
>>>>>>
>>>>>> Indeed the difference in look between X_ITE and CGE is then because of different geometry choice.
>>>>>>
>>>>>> - Castle Game Engine converts PLY mesh into IndexedFaceSet, where the creaseAngle (default 0, so flat shading) decides the look. I've done it because PLY meshes have polygons and we have already handling for possibly-concave polygons (which I understand PLY may have) at IndexedFaceSet. So we generate PLY -> IndexedFaceSet, set IndexedFaceSet.convex=FALSE, and we're done.
>>>>>>
>>>>>> - ( To be clear, this decision is not set in stone. My past experience with e.g. terrains showed that sometimes changing the generated primitive/geometry type is useful, for unforeseen reasons :) So this is _not_ a guarantee that CGE will always read PLY to IndexedFaceSet, and not e.g. IndexedTriangleSet. )
>>>>>>
>>>>>> - If X_ITE converts PLY mesh into IndexedTriangleSet, then creaseAngle doesn't exist (IndexedTriangleSet.normalPerVertex decides, and it's either all flat or all smooth).
>>>>>>
>>>>>> Indeed we're not going to reconcile this with creaseAngle.
>>>>>>
>>>>>> I think in the end, it comes down to the underlying formats -- is there any spec, or just a hint / consensus, how should normals for PLY models be generated? Does everyone create smooth meshes then, like X_ITE? If the consensus is to generate smooth normals -> then the fix is just on CGE side, we can trivially change our PLY -> IndexedFaceSet to set creaseAngle>=pi and then CGE and X_ITE will be consistent. Seems like this is the simplest way to go :)
>>>>>>
>>>>>> Hm, done in https://github.com/castle-engine/castle-engine/commit/bbbfc016ed179b2009cf8194dd692b81adf1f6e3 :) PLY teapot from https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlyIndex.html is now smooth in our rendering.
>>>>>>
>>>>>> Regards,
>>>>>> Michalis
>>>>>>
>>>>>> On Wednesday, April 8th, 2026 at 21:00, Holger Seelig <holger.seelig at yahoo.de> wrote:
>>>>>>
>>>>>>> If the teapot is faceted in Castle, it’s more likely because a different geometry was used. X_ITE converts the PLY teapot into an IndexedTriangleSet, which, as mentioned earlier, does not have a creaseAngle field.
>>>>>>>
>>>>>>> If InlineGeometry has a creaseAngle field, it gives the impression that the creaseAngle can be set for the loaded geometry, but this is only possible in the rarest of cases.
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Holger
>>>>>>>
>>>>>>> —
>>>>>>> Holger Seelig
>>>>>>> holger.seelig at yahoo.de
>>>>>>>
>>>>>>>> Am 08.04.2026 um 20:49 schrieb Holger Seelig via x3d-public <x3d-public at web3d.org>:
>>>>>>>> I would like to point out that only 4 of the 32 X3DGeometryNode's have a creaseAngle field. On the other hand, why is creaseAngle preferred here? The solid field or ccw can also be useful, but they are not available on all X3DGeometryNode's either.
>>>>>>>>
>>>>>>>> Best regards,
>>>>>>>> Holger
>>>>>>>>
>>>>>>>> —
>>>>>>>> Holger Seelig
>>>>>>>> holger.seelig at yahoo.de
>>>>>>>>
>>>>>>>>> Am 08.04.2026 um 18:13 schrieb Michalis Kamburelis via x3d-public <x3d-public at web3d.org>:
>>>>>>>>> Confirming Don's observations -- the difference in rendering of Teapot from PLY in https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlyIndex.html seems to come from difference in creaseAngle.
>>>>>>>>>
>>>>>>>>> In Castle Game Engine, when we load PLY -> we leave "IndexedFaceSet.creaseAngle" at default in X3D, which is 0, which results in flat shading ( https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/components/geometry3D.html#IndexedFaceSet ).
>>>>>>>>>
>>>>>>>>> Note that PLY files _can_ provide their own, explicit normal vectors. In which case there would be non inconsistency. But, well, this PLY model ( https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/teapot.ply ) does not provide normals. It only has vertex positions.
>>>>>>>>>
>>>>>>>>> Introducing "InlineGeometry.creaseAngle" makes sense to me.
>>>>>>>>>
>>>>>>>>> Internally, I would also allow loading options as URL anchor, so one could load "xxx.ply#crease-angle=123" thus it would be possible to influence creaseAngle also for models loaded through "Inline", like """Inline { url "model.ply#crease-angle=123" />"""
>>>>>>>>>
>>>>>>>>> Compared to Don prose, I would say to allow an option to _don't change the underlying value (or browser default)_. Because when we inline e.g. X3D geometry, then (possibly) it already has a useful creaseAngle? So I would define it like:
>>>>>>>>>
>>>>>>>>> """
>>>>>>>>> InlineGeometry {
>>>>>>>>> ...
>>>>>>>>> creaseAngle initializeOnly -1
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> creaseAngle determines the the automatic calculation of normal vectors for the imported geometry. It is only used if all of the below are true:
>>>>>>>>>
>>>>>>>>> - Given creaseAngle is >= 0. The default, -1, means to use creaseAngle specified in the imported model (if the format of it allows creaseAngle, like X3D allows) or browser-specific default.
>>>>>>>>> - Imported geometry results in X3D geometry with creaseAngle, e.g. in IndexedFaceSet. For other geometry types, like PointSet, creaseAngle is ignored.
>>>>>>>>> - Imported geometry doesn't have explicit normal values. E.g. if PLY file has explicit normal provided, then these are used, and the creaseAngle value doesn't matter.
>>>>>>>>>
>>>>>>>>> """
>>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>> Michalis
>>>>>>>>>
>>>>>>>>> On Tuesday, April 7th, 2026 at 23:52, Don Brutzman <don.brutzman at gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> Thanks for references Michalis. Here is an example test scene.
>>>>>>>>>>
>>>>>>>>>> - X3D Example Archives: X3D4AM, X3D for Advanced Modeling, Additive Manufacturing, Teapot Inline Geometry Ply
>>>>>>>>>> - Loading a classic teapot model in PLY format
>>>>>>>>>> - https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlyIndex.html
>>>>>>>>>>
>>>>>>>>>> Implementation and evaluation always helps... Note significant differences in rendering due to implicit choices for creaseAngle:
>>>>>>>>>>
>>>>>>>>>> - https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlyCastle.png
>>>>>>>>>> - https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/AdditiveManufacturing/TeapotInlineGeometryPlySunrize.png<image.png> <image.png>
>>>>>>>>>>
>>>>>>>>>> Currently the author has no settings to adjust the handling of the mesh.
>>>>>>>>>>
>>>>>>>>>> Suggestion: might we consider adding creaseAngle as a field for InlineGeometry node? It is defined in the specification as follows.
>>>>>>>>>>
>>>>>>>>>> - [X3D Architecture 4.1 draft — ISO/IEC 19775-1:202x — 11 Rendering component](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/components/rendering.html#CommonGeometryFields) [11.2.3 Common geometry fields](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/components/rendering.html#CommonGeometryFields)
>>>>>>>>>> - https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/components/rendering.html#CommonGeometryFields
>>>>>>>>>>
>>>>>>>>>>> The creaseAngle field affects how default normals are generated. If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced. Crease angles shall be greater than or equal to 0.0 angle base units.
>>>>>>>>>>
>>>>>>>>>>> EXAMPLE A crease angle of 0.5 angle base units means that an edge between two adjacent polygonal faces will be smooth shaded if the geometric normals of the two faces form an angle that is less than 0.5 angle base units. Otherwise, the faces will appear faceted.
>>>>>>>>>>
>>>>>>>>>> However, typically an author has no idea on what might be an appropriate value, unless they do extensive sleuthing on an unchanging piece of geometry. Thus we might pick a default value for creaseAngle field that always results in smooth shading.
>>>>>>>>>>
>>>>>>>>>> - SFFloat [ ] creaseAngle 3.14159 [0,+inf)
>>>>>>>>>>
>>>>>>>>>> Further descriptions found in X3D tooltips.
>>>>>>>>>>
>>>>>>>>>> - [X3D Tooltips in English version 4.0 (with X3D version 4.1 draft), IndexedFaceSet.creaseAngle](https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedFaceSet.creaseAngle)
>>>>>>>>>> - https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedFaceSet.creaseAngle
>>>>>>>>>>
>>>>>>>>>> [creaseAngle [accessType initializeOnly](https://www.web3d.org/x3d/tooltips/X3dTooltips.html#accessType), [type SFFloat](https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFFloat) [CDATA](https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CDATA) "0"] [[0,+∞)](https://www.web3d.org/x3d/tooltips/X3dTooltips.html#RangeIntervals)
>>>>>>>>>> creaseAngle defines angle (in radians) for determining whether adjacent polygons are drawn with sharp edges or smooth shading. If angle between normals of two adjacent polygons is less than creaseAngle, smooth shading is rendered across the shared line segment.
>>>>>>>>>> Hint: in Interchange profile only 0 and π radians supported.
>>>>>>>>>> Hint: creaseAngle=0 means render all edges sharply, creaseAngle=3.14159 means render all edges smoothly.
>>>>>>>>>> Hint: radian units for angular measure https://en.wikipedia.org/wiki/Radian
>>>>>>>>>> all the best, Don
>>>>>>>>>> --
>>>>>>>>>> X3D Graphics, Maritime Robotics, Distributed Simulation
>>>>>>>>>> Relative Motion Consulting [https://RelativeMotion.info](https://relativemotion.info/)
>>>>>>>>>>
>>>>>>>>>> On Mon, Apr 6, 2026 at 5:26 PM Michalis Kamburelis <michalis at castle-engine.io> wrote:
>>>>>>>>>>
>>>>>>>>>>> As for black points reported by John in some PLY files: Fixed.
>>>>>>>>>>>
>>>>>>>>>>> I added to Castle Game Engine / Castle Model Viewer support for reading color values from PLY through alternative properties. Details and links to more explanation in commit https://github.com/castle-engine/castle-engine/commit/c6d9acc08aa7a20e991b140d1379e265ea496faf . Screenshot attached.
>>>>>>>>>>>
>>>>>>>>>>> Note: All this is doing is adding alternative way to read colors from PLY, which lands in X3D per-vertex colors (Color or ColorRGBA node).
>>>>>>>>>>>
>>>>>>>>>>> I'm not entering the Gaussian Splat discussion in related thread(s) :), as I have to educate myself better about Gaussian Splats first. Tomorrow's Khronos lecture seems like a good opportunity to start learning.
>>>>>>>>>>>
>>>>>>>>>>> Regards,
>>>>>>>>>>> Michalis
>>>>>>>>>>>
>>>>>>>>>>> On Monday, April 6th, 2026 at 20:49, John Carlson via x3d-public <x3d-public at web3d.org> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Sorry I meant I was able to see black point clouds without color (Michalis apparently uses different properties?).
>>>>>>>>>>>>
>>>>>>>>>>>> On Mon, Apr 6, 2026 at 1:00 PM John Carlson <yottzumm at gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> I agree that the PLYs that I worked with weren’t suitable for X3D. Either my parser was off, or there were negative color values, negative scales etc. I thought a second person could look at the same files and make better progress. I was able to view black points clouds (no clouds) from the PLY files in castle. I can probably change the property in the PLY file to achieve color in the point cloud. The point is, I don’t know if there’s standard PLY color properties.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>
>>>>>>>>>>>>> John
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Mon, Apr 6, 2026 at 12:18 AM Don Brutzman <don.brutzman at gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thank you Michalis for implementing the draft InlineGeometry node. Having both Castle Game Engine and (already supporting) X_ITE/Playground/Sunrize is definitely accelerating our design, implementation and evaluation of LOA-5 bone segments for HAnim. Tests of your Castle Model Viewer beta release look good on this end.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Repeating a prior reply: "Gaussian Splat PLYs" (whatever that means) does not seem like a good use of effort. There is a lot of ongoing developmental work on gaussian splat formats by various companies that are nonstandard, inconsistent, possibly unstable, and often proprietary. Some happen to use .ply as a container. A prudent approach is to wait and see what glTF does once things stabilize. Using Inline with glTF 2.0 (in json or glb) is already in X3D 4.0, extension support by browsers is optional, so that is a reasonable future path if consensus ever emerges.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The draft X3D specification for InlineGeometry describes rationale and includes references for the PLY format.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> - [X3D Architecture 4.1 draft — ISO/IEC 19775-1:202x — 9 Networking component](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/components/networking.html#InlineGeometry) [9.4.3 InlineGeometry](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/components/networking.html#InlineGeometry)
>>>>>>>>>>>>>> - https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/components/networking.html#InlineGeometry
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 9.4.3 InlineGeometry
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> InlineGeometry : X3DGeometryNode, X3DUrlObject {
>>>>>>>>>>>>>> SFTime [in,out] autoRefresh 0.0 [0,infinity)
>>>>>>>>>>>>>> SFTime [in,out] autoRefreshTimeLimit 3600.0 [0,infinity)
>>>>>>>>>>>>>> SFString [in,out] description ""
>>>>>>>>>>>>>> SFBool [in,out] load TRUE
>>>>>>>>>>>>>> SFNode [in,out] metadata NULL [X3DMetadataObject]
>>>>>>>>>>>>>> MFString [in,out] url [] [URI]
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> InlineGeometry loads geometry from an external file. The result provides a polygonal mesh, set of lines, point cloud, parametric surface, or other geometry.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The url field can support loading a variety of file formats defining polygonal mesh geometry. When the url field contains no values ([]), no default geometry is provided. Required Recommended support by X3D browsers includes both ASCII and binary encodings for the STL format (see [STL](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/bibliography.html#STL)) as well as the PLY polygonal geometry format (see [PLY](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/bibliography.html#PLY)), respectively. Other file types can be optionally supported by a browser.
>>>>>>>>>>>>>> TODO: consider "required support" of STL/PLY formats rather than "recommended support" since numerous open-source conversion implementations are available, no IPR considerations pertain, and STL/PLY formats are the primary use case.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> If the url field refers to an X3D file or a VRML97 file, the first geometry node found in that file (excluding both prototype declarations and prototype instances) is used to provide the InlineGeometry contents. X3D browsers shall recognize url fields that end with "#DEFname" to mean the geometry node with DEF label of DEFname in the given X3D or VRML97 file.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The run-time system can support any number of 3D model resource types as long as those follow the available Model Primary Content Type for Multipurpose Internet Mail Extensions (MIME) model definition (see [RFC2077](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/references.html#RFC2077)), provide a registered content type (e.g., model/stl, text/plain etc.) (see [IANA_MEDIA](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/references.html#IANA_MEDIA) and [IANA_STL](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/references.html#IANA_STL)), and can be determined with some form of content negotiation (see [RFC9110](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/references.html#RFC9110)). Support is recommended for both text and binary encodings associated with a given model format, when so defined.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> NOTE Experimental variations of PLY format used for Gaussian Splat rendering are not expected for InlineGeometry. Such capabilities are better supported by Inline node loading of glTF models.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> EXAMPLES
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Shape {
>>>>>>>>>>>>>> geometry InlineGeometry { url [ "MyFavoriteMesh.stl" ] }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> appearance USE FancyPaintAppearance # previously defined
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Shape {
>>>>>>>>>>>>>> geometry InlineGeometry { url [ "HelloWorld.x3d#TextMessage" ] }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> appearance USE FancyPaintAppearance # previously defined
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Editors notes.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> - Are better authoritative references possible for STL and PLY? See [Mantis 1522](https://mantis.web3d.org/view.php?id=1522).
>>>>>>>>>>>>>> - InlineGeometry results differ from an Inline node, which produces an X3DChildNode scene subgraph implementing the X3DBoundedObject interface. An Inline node cannot be used as the geometry field of a Shape.
>>>>>>>>>>>>>> - Results from browser loading may be any kind of polygonal mesh or parametric surface (e.g. IndexedFaceSet, TriangleSet, Extrusion, etc.) but cannot be further manipulated or animated by events from the scene.
>>>>>>>>>>>>>> - Direct loading of such geometry files eliminates the need for prior model conversion into X3D, and adds flexibility when applying Appearance to the result.
>>>>>>>>>>>>>> - The "#DEFname" syntax directly matches [EXTERNPROTO URL semantics](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD//Part01/concepts.html#EXTERNPROTOURLSemantics) considerations. Not requiring IMPORT/EXPORT statements provides greater backwards compatibility with legacy models, avoiding unnecessary complications and possible ambiguity.
>>>>>>>>>>>>>> - Composition of online addresses and parameter values within a url field offers the possibility of invoking an online server to perform file-format conversions. See email thread [[x3d-public] Inline > type field > for loading / converting / parsing other content](https://web3d.org/pipermail/x3d-public_web3d.org/2026-March/022355.html) for further discussion. Such additional functionality supports the use cases under consideration by Metaverse Standards Forum (MSF) [3D Web Interoperability](https://metaverse-standards.org/domain-groups/3d-web-interoperability) Working Group.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Worth reading: the original PLY definition first defined in 1994 by Greg Turk at Stanford University., references above.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> - [[PLY](https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/bibliography.html#PLY)]
>>>>>>>>>>>>>> - https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4.1-CD/Part01/bibliography.html#PLY
>>>>>>>>>>>>>> - Wikipedia, PLY (file format), 26 February 2026. https://en.wikipedia.org/wiki/PLY_(file_format)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> - Greg Turk. ["The PLY Polygon File Format"](https://web.archive.org/web/20161204152348/http://www.dcs.ed.ac.uk/teaching/cs4/www/graphics/Web/ply.html). Archived from [the original](http://www.dcs.ed.ac.uk/teaching/cs4/www/graphics/Web/ply.html) on 2016-12-04.
>>>>>>>>>>>>>> - Greg Turk. ["The PLY Polygon File Format (extended)"](https://gamma.cs.unc.edu/POWERPLANT/papers/ply.pdf) (PDF).
>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> - [PLY - Polygon File Format](https://paulbourke.net/dataformats/ply/)https://paulbourke.net/dataformats/ply
>>>>>>>>>>>>>> Improvements to draft specification, especially with implementation and evaluation, are always welcome.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> all the best, Don
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> X3D Graphics, Maritime Robotics, Distributed Simulation
>>>>>>>>>>>>>> Relative Motion Consulting [https://RelativeMotion.info](https://relativemotion.info/)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Sun, Apr 5, 2026 at 6:39 PM John Carlson via x3d-public <x3d-public at web3d.org> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi, Michalis, Seeing Gaussian Splat PLYs renderered with humanoid animation would be cool to see. With your expertise in binary formats and binary PLY, probably an easy next step!
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> John
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Sun, Apr 5, 2026 at 8:05 PM Michalis Kamburelis via x3d-public <x3d-public at web3d.org> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> With big thanks to Don who provided information and pushed me to implement it!:)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 1. We support now InlineGeometry in Castle Game Engine and Castle Model Viewer.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - I tested on a few examples, and made our own: https://github.com/castle-engine/demo-models/tree/master/x3d/inline_geometry
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - You can refer to a geometry from any model format we support, including X3D, glTF, STL, PLY...: https://castle-engine.io/model_formats
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2. We support now loading models in a PLY format.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - ASCII and binary versions.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - Faces or without faces (point cloud, i.e. just our PointSet).
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - Testcases include https://github.com/castle-engine/demo-models/tree/master/ply and https://sketchfab.com/3d-models/kaktus-ply-7b7cc7188f17468595506500e186a9c0 .
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> More information and screenshots about both features in our news post on https://castle-engine.io/wp/2026/04/06/support-for-ply-model-format-and-inlinegeometry-node/ .
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> They are available to test right now if you download
>>>>>>>>>>>>>>>> - the "snapshot" version of Castle Model Viewer https://castle-engine.io/castle-model-viewer
>>>>>>>>>>>>>>>> - or full engine from https://castle-engine.io/download .
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Regards,
>>>>>>>>>>>>>>>> Michalis
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>> x3d-public mailing list
>>>>>>>>>>>>>>>> x3d-public at web3d.org
>>>>>>>>>>>>>>>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>> x3d-public mailing list
>>>>>>>>>>>>>>> x3d-public at web3d.org
>>>>>>>>>>>>>>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> x3d-public mailing list
>>>>>>>>> x3d-public at web3d.org
>>>>>>>>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> x3d-public mailing list
>>>>>>>> x3d-public at web3d.org
>>>>>>>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>>>>>>
>>>>>> _______________________________________________
>>>>>> x3d-public mailing list
>>>>>> x3d-public at web3d.org
>>>>>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20260418/b0c14f5c/attachment-0001.html>
More information about the x3d-public
mailing list