Blender Serial Control Addon - blendixserial

Introduction:

blendixserial is a Blender add-on that allows you to control the movement of 3D objects in Blender via Simple UART (Serial Communication). It provides a user interface panel in the Blender 3D View where you can connect/disconnect from a serial port, start/stop object movement, and control the movement of multiple objects in the scene. When you start the movement, the add-on continuously reads data from the serial port and updates the positions of the selected objects based on the received data. The movement is applied to the specified axes (X, Y, Z) for each object and property. For example, if you choose to control the location of an object along the X-axis and the rotation along the Y-axis, the add-on will interpret the received data and update the object's position and rotation accordingly. You can select a text object within the scene that will display the current movement values for each controlled object. The add-on will update the text object with the updated position, rotation, or scale values as the objects move. For example, if you have a text object named "Text" associated with an object named "Object1", the add-on will continuously update the "Object1 Text" object to display the current position, rotation, or scale values of "Object1" based on the received data.

Requirements:

Blender version 3.5.1 or later

Installation:

1. Open Blender and go to Edit -> Preferences.
2. In the Preferences window, click on the Add-ons tab.
3. Click the Install... button.
4. Browse and select the blendixserial zip file.
5. Enable the checkbox next to the " blendixserial " add-on to activate it.
6. The add-on is now installed and ready to use.

License:

This program is distributed under the terms of the GNU General Public License version 3 (GPLv3). You are free to redistribute and modify this program in compliance with the terms of the license. For more details, refer to the GNU General Public License page.

Features:

The addon's functionality revolves around the concept of timers. By registering a specific function, such as the update scene method, with bpy.app.timers.register(), the addon ensures that the function is executed periodically during the animation rendering process. This approach allows for precise control over when and how the animation updates occur. The timer-based approach provides a way to create dynamic and automated animations without manual intervention.
In the Blendix Serial panel, there are different options available for controlling object movement. To initiate the movement of objects, you can use the "Start Movement" and "Stop Movement" buttons respectively. If you want to specify the update delay for the scene, you can adjust the "Update Scene Delay" slider. This slider determines the time interval between updates for the scene.
This addon uses two modules called threading and queue to handle multiple tasks at the same time and to send data between different parts of the addon. The main purpose of using threading and a queue in this addon is to separate the process of reading data from the serial port and updating the Blender scene. By using a separate thread for reading data, the addon can continuously receive data while the scene is being updated and vice versa. The use of a queue ensures that data is processed in the order it was received, avoiding any loss or corruption of data.

Threading
The threading module is used to create a separate thread called serial thread(). This thread reads data from the serial port. This allows the Blender UI to stay responsive while data is being received in the background. The serial thread() function checks if there is data available in the serial port's input buffer. If data is available, it is read and added to the data queue for further processing.

Queue
The queue module is used to create a thread-safe queue called data_queue. This queue acts as a buffer to store the incoming data from the serial port. The data_queue is an instance of the queue. Queue class. The serial thread() function reads data from the serial port and puts it into the data_queue, and the main thread (update scene()) retrieves and processes the data from the data queue. Using a queue ensures that data is safely transferred between threads without any race conditions or conflicts.

Serial Connection Management
Connect to a serial port with specified baud rate.
Disconnect from the serial port.

Update Scene Delay
By adjusting the delay value, you can control the rate at which the scene updates and how frequently the visual representation of the data changes in the Blender viewport. A smaller delay value will result in more frequent updates and a smoother real-time visualization, while a larger delay value will slow down the updates and potentially result in a less responsive visualization. By default, it is set to 0.01, but it can be adjusted within a range of 0.001 to 2.

Object Movement
Control the movement of objects within the Blender scene by managing their position, rotation, and scale. You can choose which axes (X, Y, Z, XY, XZ, YZ, XYZ) to apply movement to. Customize properties such as location, rotation, and scale for each object. Keep the object movement updated based on data received from the serial connection. Additionally, you have the ability to pause and resume object movement.

Text Object Update
Update text objects in the Blender scene by incorporating received data. Configure specific text objects to display information from individual objects. This dynamic update of text information enhances visualization and facilitates communication.

User Interface

The user interface features a Movement Control panel integrated into the Blender 3D View, providing a user-friendly experience. Easily connect and disconnect from the serial port using dedicated buttons. Initiate and stop object movement with a single click. Select objects and adjust their properties, axes, and associated text objects. Reset object transformations to their default values when needed.

Error Handling
To ensure smooth operation, informative error messages are provided in case of connection failures or invalid data received from the serial port. The script handles potential exceptions gracefully, maintaining stability and usability.


Rendering🔎

3D Viewport Real-time VS Final Real-time

Real-time rendering, which aims to display a scene at interactive frame rates, can be achieved in the 3D viewport. However, achieving real-time rendering in the final output (such as a rendered video or image sequence) with high-quality and complex scenes can be challenging. Real-time rendering in the viewport prioritizes speed and interactivity over quality and accuracy. It may utilize simplified rendering techniques, lower-resolution textures, and reduced complexity to maintain smooth performance. This allows you to preview and interact with the scene in a responsive manner. On the other hand, final rendering aims to produce a high-quality output with advanced rendering techniques, such as global illumination, ray tracing, and high-resolution textures. These techniques require more computational resources and time to calculate and produce the final result accurately.
The blendixserial addon uses a timer-based technique to animate objects within the scene. This technique involves registering a timer that calls a specific function repeatedly at regular intervals. In this case, the update_scene function is registered with bpy.app.timers.register() to automate actions and updates in the scene. By utilizing timers, the addon can control the timing and frequency of object movements or other changes. The update_scene function is responsible for updating the state of the objects based on the desired animation logic.

In the viewport, you can adjust the update scene delay and optimize the scene to achieve a smooth real-time display. By reducing the update scene delay, you can increase the frequency at which the scene is updated, resulting in smoother motion and a closer representation of real-time. However, when it comes to final rendering for videos or images, achieving real-time rendering in the strictest sense, which means rendering an entire frame within the time it takes to display that frame, may not be possible. You can test this feature in the final real-time rendering process, and if you succeed, I would appreciate it if you could share your results with me as well.



Conclusion
The blendixserial for Blender enhances the interactive capabilities of the Blender environment by enabling users to control object movement through a serial connection. With the ability to update object properties and display data in real-time, users can create dynamic animations, interactive visualizations.

Data Format

The blendixserial add-on is designed to receive data in a specific CSV format through a serial communication interface. The add-on expects the incoming data to be in the following CSV format:

x1, y1, z1, x2, y2, z2, x3, y3, z3; text data
Each set of coordinates (x, y, z) represents the position or rotation values for three different objects in a 3D scene. The coordinates values are separated by commas, and the entire coordinates data and text data are separated by a semicolon. Here's an example of valid data in the expected format:


1.0, 2.5, 3.7, -0.5, 1.2, 0.0, 2.8, 0.1, -1.5; Hello, world! 

In this example, there are three objects with their respective coordinates (x, y, z) provided. The text data field contains the string "Hello, world!". The add-on parses this data and updates the position, rotation, and text of the specified objects in the Blender scene accordingly. The object properties to be updated (e.g., location or rotation Euler) are determined based on the user's configuration within the add-on's interface.

Please ensure that the data being sent over the serial communication interface follows this format to ensure proper functionality of the blendixserial add-on.

Addon Testing Example:


void setup() {
  Serial.begin(115200); // Initialize serial communication with a baud rate of 115200
}

void loop() {
  sendtoBlender(); // Call the sendtoBlender function repeatedly in an infinite loop
}

// Function to generate random meaningful words
String generateRandomText(int length) {
  String randomText = "";

  // Define an array of meaningful words
  String words[] = {"apple", "banana", "cat", "dog", "elephant", "flower", "guitar", "house", "ice cream", "jungle"};
  int numWords = sizeof(words) / sizeof(words[0]);

  for (int i = 0; i < length; i++) {
    int randomIndex = random(0, numWords); // Generate a random index to select a word from the array
    String randomWord = words[randomIndex];
    randomText += randomWord + " ";
  }

  randomText.trim(); // Remove the trailing space

  return randomText;
}

// Function to generate random axis values
String generaterandomAxis() {
  String axis = "";
  float x1 = random(-10, 10); // Generate a random floating-point number between -10 and 10 for x1
  float y1 = random(-10, 10); // Generate a random floating-point number between -10 and 10 for y1
  float z1 = random(-10, 10); // Generate a random floating-point number between -10 and 10 for z1
  float x2 = random(-5, 5);   // Generate a random floating-point number between -5 and 5 for x2
  float y2 = random(-5, 5);   // Generate a random floating-point number between -5 and 5 for y2
  float z2 = random(-5, 5);   // Generate a random floating-point number between -5 and 5 for z2
  float x3 = random(-15, 15); // Generate a random floating-point number between -15 and 15 for x3
  float y3 = random(-15, 15); // Generate a random floating-point number between -15 and 15 for y3
  float z3 = random(-15, 15); // Generate a random floating-point number between -15 and 15 for z3

  String random_axis = String(x1) + "," + String(y1) + "," + String(z1) + ","
    + String(x2) + "," + String(y2) + "," + String(z2) + ","
    + String(x3) + "," + String(y3) + "," + String(z3);

  axis += random_axis; // Concatenate the generated axis values into a single string

  return axis;
}

// Function to send data to Blender
void sendtoBlender() {
  String textData = generateRandomText(3); // Generate random meaningful text with a desire length
  String movementData = generaterandomAxis(); // Generate random axis values
  String sendData = movementData + ";" + textData; // Combine the axis values and text data with a semicolon in between

  Serial.println(sendData); // Print the combined data to the serial monitor for communication with Blender
  delay(200);
}

Data Format Explanation:

The code sends data to the Serial in a specific CSV format that consists of movement data and text data.

Movement Data Format:
The movement data represents motion in three different directions: x, y, and z. It is divided into three sets, with each set containing values for a specific direction.

Format: x1, y1, z1, x2, y2, z2, x3, y3, z3

x1, y1, and z1 represent the motion values in the first set for the x, y, and z directions, respectively.
x2, y2, and z2 represent the motion values in the second set.
x3, y3, and z3 represent the motion values in the third set.
Each value represents the motion magnitude along the corresponding axis.

Text Data Format:
The text data is appended to the movement data. It adds variability to the data sent via the Serial.

Format: Text

Complete Data Format:
The complete data format combines the movement data and text data.

Format: x1, y1, z1, x2, y2, z2, x3, y3, z3; Text 

The movement data is provided first, with values separated by commas. After the semicolon, the text data follows.

Example: -2.35,6.72,0.91,4.12,2.83,-1.57,-11.22,-8.67,14.98;apple banana cat

In this example, the generated axis values are -2.35, 6.72, 0.91, 4.12, 2.83, -1.57, -11.22, -8.67, 14.98, and the generated text is apple banana cat. The axis values represent three sets of coordinates: (x1, y1, z1), (x2, y2, z2), and (x3, y3, z3). The text data represents three randomly generated Text. Each time the sendtoBlender() function is called in the loop() function, a new set of random data will be generated and printed to the serial monitor.


Download


Video