Adjust Mesh surface color in Three.js with the help of a Raycaster

I'm currently developing a web application that changes the color of faces when hovered over by a Raycaster (mouse).

The application includes a functioning .stl viewer and orbital controls.

To test my code using a validated .stl file, visit my GitHub repository. You can easily run it with a live server, which can be set up in tools like VSCode, as explained in the readme.

Although the code successfully changes the object's color entirely, attempting to change the facecolor through the raycaster's intersects method does not produce the desired result. I have already added vertexColors: THREE.VertexColors to the material properties, as recommended.

While the color value shows a change when logging the face's color property, visually, there is no visible alteration upon executing

intersects[i].face.color.setHex(0x0f0f0f)
.

I suspect I may have overlooked or missed something essential, but I am struggling to identify the issue.

Below is my current code snippet:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Viewer by Tjalle</title>
    <link rel="stylesheet" type="text/css" href="../style/render.css">
</head>

<body>
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r117/build/three.min.js"></script>
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r117/examples/js/loaders/STLLoader.js"></script>
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r117/examples/js/controls/OrbitControls.js"></script>

    <script>
        function init() {
            // Code for initializing and rendering the 3D view
        }

        init();
    </script>

</body>

</html>

Answer №1

The face aspect of the intersection object cannot be altered, as it is read-only. This means any modifications made to it will not update the actual geometry data.

It's important to note that when working with BufferGeometry, geometries are represented through vertex data without a face abstraction like the older Geometry class. Therefore, if you wish to alter colors per face, you must ensure that there are no shared vertices in your geometry's face definitions. Simply put, this can only be achieved with non-indexed geometries. Luckily, STLLoader exclusively provides non-indexed geometries.

The vertex color data are stored in a color buffer attribute, which can be accessed using

const colorAttribute = geometry.getAttribute( 'color' );
. To incorporate your desired feature, you need to update the color values within this buffer attribute following this pattern:

const face = intersects[ 0 ].face;
const color = new THREE.Color( Math.random() * 0xffffff ); // random color

const colorAttribute = geometry.getAttribute( 'color' );

colorAttribute.setXYZ( face.a, color.r, color.g, color.b );
colorAttribute.setXYZ( face.b, color.r, color.g, color.b );
colorAttribute.setXYZ( face.c, color.r, color.g, color.b );

colorAttribute.needsUpdate = true;

If STLLoader doesn't generate a color buffer attribute, you may need to create one yourself.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The div element is unable to activate the modal due to tabindex issues

Seeking Assistance with a Specific Scenario I have a specific layout where a div is enclosing an image. The desired functionality is that when the div is clicked with a mouse, a small tooltip modal should appear displaying address information. This can be ...

Find the identification number by searching through the text

I'm trying to find a way to retrieve the node id during a text search. Here's an example: http://jsfiddle.net/53cvtbv9/529/ I attempted using two methods to get the id of a node after the search: console.log($('#jstree').jstree(true). ...

Implementing service injection within filters in NestJS

Looking to integrate nestjs-config into the custom exception handler below: import { ExceptionFilter, Catch, ArgumentsHost, Injectable } from '@nestjs/common'; import { HttpException } from '@nestjs/common'; import { InjectConfig } fro ...

Resolving the issue of "Cannot GET" error with Node.js and Express

I have a class named Server in Server.js: const express = require('express'); class Server { constructor() { this.app = express(); this.app.get('/', function(req, res) { res.send('Hello World&apos ...

Stack two divs together

It may seem silly, but I just can't get it to work. I'm attempting to enclose two divs with different classes in another div, but my current code is automatically closing the divs. There are multiple sets of divs with classes .panel-heading and ...

What could be causing AngularJS to truncate my URL in the search bar?

Currently, I am in the process of setting up a state provider for a CRUD website. One issue I encountered is that when I navigate to www.mysite.com/posts/mypost, the URL gets shortened to www.mysite.com/mypost and does not trigger the controller as intend ...

The jquery error NS_ERROR_XPC_BAD_CONVERT_JS is causing issues on Google Chrome while working fine on Firefox

Currently, I am utilizing jQuery to dynamically add fields to a form. These are considered "repeatable" fields since users can click an "add more" button. Here is the code snippet: $(".add-attacker-scores").click(function() { count = count + 1; ...

Include onload to element without running it in Puppeteer

I am currently developing a web scraping tool using Puppeteer. Once the webpage is fully loaded, I need to update the HTML code and include an onload event for certain elements. The issue is that in Puppeteer, the onload event is actually triggered automa ...

I possess an array with a specific structure that I wish to substitute the keys as demonstrated below

The data array is currently structured in this way. I have attempted various methods but have not been able to find a suitable solution. I need to send the JSON below via an AJAX request, however, I do not want the keys 0 and 1 in both child arrays. [sch ...

Adding a class-matched element with a corresponding ID

Despite finding similar questions, I am still unable to achieve the desired outcome. Here is a list: <ul> <li class="class1"></li> <li class="class2"></li> <li class="class3"></li> <li class="class4"&g ...

Using CSS properties as false values within React applications

Can you provide guidance on using conditional styles with conditional operators? What would be the ideal code example? Is it possible to use non-CSS values? margin: isOpen ? '10px' : undefined margin: isOpen ? '10px' : 'initial&a ...

Obtaining the content within a <script> tag with Selenium

Currently, I am developing a web scraper, and the website I am scraping contains a script element that looks like this: <script type="text/javascript"> jQuery(window).load(function($) { Morris.Line({ ...

Updating the total in a Meteor collection based on the quantity and price

In my form, I have three input fields: quantity, price, and total. Whenever the user updates the quantity or price, I want the total field to update automatically. How can I ensure that the total is always accurate? Would using a collection hook be the be ...

Error: Trying to access the 'push' method of an undefined object of useHistory

import React from "react"; import { Route, Switch, HashRouter, useHistory } from "react-router-dom"; import Home from "../pages/home/HomeComponent"; import Splash from "../pages/splash/Splash"; import Education from ...

Extracting information from the responseText of an XMLHttpRequest

Using AJAX, I am retrieving some data that I need to manipulate after the AJAX call completes. However, I am facing an issue where I can't seem to manipulate the response. Here is the code snippet: function testAjax() { direc = "co ...

Leveraging HTTP/2 in conjunction with angularJS

As I was exploring ways to improve the performance of my web application, I came across HTTP/2. After learning about its features that can enhance website speed, I decided to implement it. Upon upgrading my browser to the latest version to enable HTTP/2 s ...

What is the method of showing a leaflet map in a particular div tag?

I want to showcase a leaflet map, but I specifically need it to be displayed in a div tag with a particular id like document.getElementById("map"). Here is the code snippet below which utilizes Vue.js: Here is the div tag where the map will be rendered: ...

Guide to reading JSON files with a personalized approach

Below is a JSON object structure that I am working with: { "db": { "name": "db", "connector": "memory" }, "MySql": { "host": "localhost", "port": 3306, "database": "users", "username": "root", "password": "", "name": "MySql", ...

What is the best way to persist form state in an Angular Lazy Loading Module?

I've set up 2 routes in my Angular 7 application, { path: 'create', component: CreateComponent }, { path: 'view', component: ViewComponent } Both of these routes are lazily loaded. The CreateComponent contains a f ...

What is the reason for the emergence of this error message: "TypeError: mkdirp is not recognized as a function"?

While running the code, I encountered an error indicating that the file creation process was not working. I am seeking assistance to resolve this issue. The code is designed to fetch data from the Naver Trend API and Naver Advertising API, calculate resul ...