React-three-fiber: LineSegments, EdgesGeometry not working

Created on 23 Nov 2019  ·  5Comments  ·  Source: pmndrs/react-three-fiber

I have noticed that when I use the lineSegments jsx element, it does not work. Is this the right way to go about it? The thing is that it renders properly if I use the primitive object.
Here is the codesandbox

Here is the code:

import React from 'react';
import './App.css';
import { Canvas } from 'react-three-fiber'
import * as THREE from "three";

const geometry = new THREE.DodecahedronBufferGeometry(1, 1)
const edges = new THREE.EdgesGeometry(geometry)
const lines = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 'red' }))

function EverythingFails() {
  return (
    <lineSegments>
      <edgesGeometry attach="geometry">
        <dodecahedronBufferGeometry args={[1, 1]} attach="geometry" />
      </edgesGeometry>
      <lineBasicMaterial color="red" attach="material" />
    </lineSegments>
  )
}

function EverythingWorks() {
  return <primitive object={lines} />
}

function App() {
  return (
    <Canvas>
      <EverythingFails />
    </Canvas>
  );
}

export default App;

Here is the error I got:
image

Most helpful comment

  const geom = useMemo(() => new THREE.DodecahedronBufferGeometry(1, 1))
  return (
    <lineSegments>
      <edgesGeometry attach="geometry" args={[geom]} />
      <lineBasicMaterial color="red" attach="material" />
    </lineSegments>
  )

https://threejs.org/docs/index.html#api/en/geometries/EdgesGeometry

````
Constructor
EdgesGeometry( geometry : Geometry, thresholdAngle : Integer )

Properties

Any modification after instantiation does not change the geometry.
````

nothing we can do here, threejs for some reason seals the edgesGeometry object. 🤷‍♂️

All 5 comments

  const geom = useMemo(() => new THREE.DodecahedronBufferGeometry(1, 1))
  return (
    <lineSegments>
      <edgesGeometry attach="geometry" args={[geom]} />
      <lineBasicMaterial color="red" attach="material" />
    </lineSegments>
  )

https://threejs.org/docs/index.html#api/en/geometries/EdgesGeometry

````
Constructor
EdgesGeometry( geometry : Geometry, thresholdAngle : Integer )

Properties

Any modification after instantiation does not change the geometry.
````

nothing we can do here, threejs for some reason seals the edgesGeometry object. 🤷‍♂️

Thanks @regalstreak for posting this issue just ran in the same today.
Thanks @drcmda for the explanation!
Does it mean that whenever we encounter an API that has this property of not changing we are not able to use the declarative component and we should go for the imperative approach from THREE?

You can always use args declaratively, . When args change it will fully re-construct the object, because these types of objects run init code in the constructor.

In this particular case the parent wants a reference to the child, which in React is not idiomatic. In other words, there is no obvious way to do this in React. In most situations you can mutate, then you have "attach/Object/Array", thank goodness. But looks like in this case you can't - therefore, yes, imperative.

I would suggest you open a feature request on the threejs git. Just ask them if it would be possible for this object to run the init code in a setter. If they start cleaning these static objects up it would be better for us, and for three. They create massive confusion, also in plain threejs, where suddenly some objects behave differently.

I understand, that makes sense indeed. Thanks for the explanation!

Thanks a lot for the clarification, closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dghez picture dghez  ·  5Comments

brandonreid picture brandonreid  ·  3Comments

LordOkami picture LordOkami  ·  8Comments

objectisundefined picture objectisundefined  ·  4Comments

janvarsa picture janvarsa  ·  3Comments