SSブログ

Blender extrusion, normal direction, and the order of vertices [技術]

I wrote an article about Blender extrusion about a year ago. I now understand the logic behind extrusion, verticies, and direction of normals:

Order the vertices counter-clockwise and pull them up. The normals will be directed outward.

It appears like this is a common practice for usual CAD programs. Related articles:

Autodesk
The order of vertices around the face determine the direction of the face (whether a side of the polygon is the front or the back). For example, if you place vertices in a clockwise direction, the face normal points downward. If you place vertices in a counter-clockwise direction, the face normal points upward. See Create a polygon mesh.

FreeCAD Forum
  Vertices go clockwise around the normal direction.

No, they're counter-clockwise normally.

Stack Overflow
The vertices should be in counter-clockwise order when the vertices are viewed from outside of the object. (Obviously, viewing from inside the object they are then in clockwise order).

The normal should point outward.

File Format

This is a description about STL file.
  • The direction of the normal is outward
  • The vertices are listed in counter-clock-wise order from outside, obeying the right-hand rule.


nice!(0)  コメント(0) 
共通テーマ:日記・雑感

Failed attempt to tune long distance file transfer across continent between Linux and MacOS [技術]

Conditions
I live in Japan, using a Macbook with MacOS Catalina. A CentOS file server exists at the other end of the Eurasian continent, 9 time zones away. It is maintained by some other organization and I have no control over its behaviour, except by configuring parameters on the client side.

I want to pull 30+ files, >1GB in total, from the file server over HTTPS using curl. It completes quite fast if I use a Linux on Intel NUC that resides in our office. It takes less than 20 minutes. However, it takes more than 6 hours from my Macbook with the same network conditions, so my Macbook is more than 10 times slower than the Linux box with regard to file transfer speed in this specific setup. If I pull a huge file from a CDN site with my Macbook, it is very fast. So the LAN and the local ISP line are fine at least.

To ensure the User-Agent does not affect the transfer speed, I used Linux UA on Mac and vice versa and measured the speed using curl on both platforms. It did not make any difference: Linux client is always 10+ times faster than Macbook client.

Observations
So I captured packets on my Macbook as well as on the Linux in the office and compared them. There are several notable differences in the two packet captures.

1. Macbook starts TCP handshake with ECN and CWR flags turned on. This is the indication that the client wants to establish a TCP connection with ECN (Explicit Congestion Notification). (blog article, Wikipedia)
TCP-handshake-Mac-Linux.png
On the other hand, Linux client initiates TCP handshake without ECN flags.
TCP-handshake-Linux-Linux.png
2. Packets taken on the Linux box have lots of TCP segments with their sizes much larger than the usual segment size (like 12,378 bytes instead of around 1,400 bytes). If I specify "tcp.len > 1448" display filter in Wireshark, it filters out all packets from the Mac pcap. On the other hand, a display filter of "tcp.len > 10000" shows more than 80 packets on the Linux pcap. This is an indication that the file server (Linux) uses TCP segmentation offload against the Linux client, but not against MacOS.

 Server (far away)Client 1Client 2
OSCentOSCentOS 6.8MacOS Catalina
ApplicationApache 2.4.6Curl 7.19.7Curl 7.64.1
File Transfer Speed from the Server-~1.2MB/s<100KB/s
TCP HeaderWindow Size Value289601460065535
Explicit Congestion Notificationon if askedoffon
Segmentation Offload (server)-onoff
Maximum Segment Size1380 for Client 1
1460 for Client 2
14601460
Window Scale776
Selective ACKpermittedpermittedpermitted
Max Ethernet Frame Received by tcpdump-16,482 bytes1,514 bytes


Maybe the server does not like the advertised window size value, 65535, larger than its own, 28960, or maybe ECN is the root cause, or maybe something else. Who knows. This needs experimenting.

Increase mbuf clusters
This article describes a way to increase mbuf clusters on MaOS. Recent versions of MacOS has SIP, and you need to boot to the recovery mode if you want to change boot-args by the nvram command. Then also execute the sysctl commands to tune TCP parameters as described in the page.

Result: no improvements. File transfer using curl seems slower with the changes.

TCP parameters
This article is a bit outdated, but has some TCP tuning tips. I have tried them along with the above technique, but it did not help speedup the transfer either.


That's as far as I could get. Does anyone know how such file transfers can be sped up? I am hoping that there is a way for MacOS client to cause the Linux file server to use TCP segmentation offload. I just cannot find out how.
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

WiFiよ、さようなら [技術]

コロナで在宅勤務が増えたせいか、はたまた休校になって暇な子供が四六時中YouTubeでも見ているのか、仕事している部屋でWiFi接続が遅くなったり切れたりするようになった。居間に置いてあるWiFiルーターと仕事部屋は少し離れていて、間に壁やら家具やらがあるのも影響しているのかも。仕事で使うためにスマホを何台も会社から持ち帰っていて、自宅のWiFiルーターに接続する機器は私物も含めると10台以上ある。そのうち3-4台は常時オンラインなのも原因かもしれない。

自宅(マンション)でPCやスマホのWiFi接続ツールを見ると、場所と時間によっては20程度のアクセスポイントが乱立していて、時には自分のWiFiルーターの電波よりも強い電波が飛び交っているようだ。5GHz帯は時々チャンネル設定がリセットされてしまうので、うちでは安定せず実用にならない。仕方なく2.4GHz帯を主に使うのだが、ご近所と取り合うことになっている模様。空いていそうなチャンネルを使うようにWiFiルーターの設定を調整したがあまり改善しない。

ZOOM等の会議が途中で切れることが増えてきたので、仕事中はWiFiは止めることにした。近所の電器店で今さらUSB-C Ethernetアダプターとフラットケーブルを買ってきたところ、ネットワークが安定して快適になった。

ということで今日から有線に先祖返り。
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

FlashForgeのメタルフィラメントのパラメータ [技術]

Adventurer3に付属していた赤色のフィラメントが足りなくなってきたので、しばらく逡巡して結局アルミニウムのメタルフィラメントを購入しました。

リンク先のページに「プラットフォーム欄」があり、メタル系でないフィラメントのページでは温度が書いてあるのですが、このアルミニウムのフィラメントでは「不要」と書かれています。この意味がわからずにあれこれ考えたのですが、とりあえず0度でやってみたところ大失敗。縁が反り上がり波打ってしまいました。最初から兆候はあって、しばらく眺めていても改善の兆しがないので10分程度で中断しました。

その後、プラットフォーム温度80度で別の立体の出力を行ったら今度は温度が高すぎたのか、層が積み重なるにつれて左方向にずれていって、これも成功とは言い難い結果に。最初から最後までずれているので、横から見ると斜めになっているのが明らかです。そういえば以前に赤フィラメントで出力した立体も最下層が少しずれていることがありましたが2-3層程度で、最後までずれ続けるようなことはなく、ここまで極端ではありませんでした。週末なので販売会社のサポートの電話も使えません。

海外のサイトも見てみましたが、MetalのHot Bed Temp.欄はNot Necessaryと書かれています。日本語ページも英語ページもこれでは意味がわかりません。本当に推奨温度はないのかな。スペック表修正してくれないかな。

一夜明けて天気がよく気分がいいので、適当な温度で何度か試してみたところ、40度が良さそうです。一部ズレはあります。また、brimやraftは使っていないので、最下層が全体的に外に広がっています。ほんのちょっとですけどね。これは過去にも経験があるので諦めます。(その後も何度か試したところ、70度でラフトをつけるとうまくいきましたので、下の表を訂正しました。)

以下、忘れないように、成功したときにFlashPrintでgxファイルに書き込まれたパラメータです。

パラメータ
Layer Height0.18mm
Perimeter Shells2
Fill Density15%
Fill PatternHexagon
Print Speed60mm/s
Travel Speed80mm/s
Extruder210°C
Platform40°C70°C


解像度をHyperでスライスしたのときの層の厚さは0.08mmですが、これだとフィラメントの押し出し量が少なすぎたのか、それともプラットフォーム温度を50度にしたのが災いしたのか、木の枝のような形状のサポート材が何箇所か定着せずに糸くずのようになってしまい、失敗しました。組み合わせを網羅するのは時間的に不可能だし、無駄になるフィラメントも安くないのでこのへんで妥協しつつ、毎回微調整してみるつもりです。光造形だとこんな苦労はないんだろうなぁと思いますが、臭いがひどいらしいし、ネットの動画を見ていると後処理も面倒そうなので、当面このままフィラメントでやります。

さて、メタルフィラメントの感想です。赤のフィラメントだと表面の凹凸が見にくいのですが、アルミニウムのフィラメントは細かい凹凸までよく見えるので、その点は赤より断然いいです。平面の凹凸が見えすぎて欠点が目立つとも言えますが、最終製品ではないのでこんなものかと。金属感は思っていたほどではないです。

モデリングはBlenderに内蔵されているPythonでやっています。いつもアプリを使っていなければ画面操作は忘れますが、コードとして保存しておくと再現や調整、拡張が容易です。結構計算させるので、立体が画面上で形になるまでには何分もかかったりします。完成するまではBlenderのCPU利用率が高いまま張り付いていて、まさに計算機に仕事させてるって感じです。
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

Blender extrusion gotcha [技術]

I have been using Blender as a 3D CAD tool to design objects for a few weeks now. My goal is to output them using a 3D printer. Since I am a programmer, I do everything with Python so far. Blender has Python interpreter embedded.

Here is a tip about extrusion.

If I extrude a face with many vertices along Z axis to upwards/positive side, all the faces may have normals directed toward inside the object. Because of this inverted faces, if I export the result as STL, the object does not appear like a solid from outside. It looks as if faces appear transparent from certain angles.

BadExtrusion.png
(Click the image to see the video.)

In order to confirm the direction of normals,
  1. Select the target object.
  2. Change to "Edit Mode".
  3. Click the "v" button to the right of the "Show Overlays" button at the upper right corner.
  4. Click "Display Normals" at the bottom of the menu.
Colored sticks will indicate the direction of normals at the center of all faces of the object.

Normals directed toward outside (good)
BlenderNormalDirections1.png

Normals directed toward inside (bad)
BlenderNormalDirections2.png

To fix the direction of normals, I initially tried to flip all faces after creating the object, but it did not work well. So instead I changed the direction of extrusion to downwards/negative side along Z axis. The normals are toward outside now, and it fixed the issue in the STL output. STL preview appears exactly like the object I created in Blender.

That said, I still do not understand how Blender determines the direction of normals. So, if it fails, extrude the object to the other direction.

It did not happen in FreeCAD though. The normals are directed toward outside in FreeCAD regardless of the direction of extrusion. Therefore, I did not notice that faces had directions in FreeCAD. STL output was just fine from the beginning! Also, Flashprint app can handle STL generated by FreeCAD much better than STL generated by Blender.
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

Programming language and framework in the era of JSON over HTTP [技術]

Nowadays, there are many programming projects that are bound by network transport and data types. HTTP(S) is probably the most popular transport and there are different HTTP server frameworks for different programming languages. So what would be the programming language of choice given a task to solve involving HTTP with a particular data type?

I am writing this post after completing a web service project that has been used for product and deployment testing for a fairly large system across multiple enterprises interconnected with each other. Here are some of the characteristics of the project:
  • HTTP is used as the transport for JSON data. There is no UI involved so no need for HTML or MVC.
  • Language choice is up to myself. No one cares what language I use.
  • Performance is not the primary goal.
  • Learning curve and ease of use are important when choosing a language and a framework.
Nowadays, the data structure is JSON. JSON is transported as text data, so an ideal programming language should be able to marshal/unmarshal (serialize/de-serialize) the data to and from native representation for easy retrieval and manipulation of data.

Another constraint comes from the fact that I am Japanese living in Japan: ideally the language can handle non-ASCII strings without much struggle.

I did not have enough time to try out all the different libraries and frameworks for my task, so I only looked at the documentation and examples before deciding on which language and framework to use.

That said, I am showing working examples of all the candidate languages below. I spent several nights for research and coding for completeness.

I have tested all below codes using curl like:
curl -X POST -H "Content-Type: application/json" -d '{"name":"Taro"}' http://localhost:3000/hello

Java
My language of choice had been Java for a long time mainly due to feature-rich IDEs. However, JSON support at the language level is not comparable to other languages like JavaScript or Python. At least that was my impression off the top of my head based on my past experience with the language. I did not want to use a library that forced the user to define data structures or classes up-front before starting the real task. In any case, org.json.JSONObject may be the choice if you are bound to Java and performance is not much of a concern. The interface is intuitive for a experienced Java developer. As for the REST framekwork, Spark appears simple enough. This is a working exmple that combines Spark with JSONObject:
package SparkSample;

import static spark.Spark.*;
import org.json.JSONObject;

public class MyApp {
    public static void main(String[] args) {
        post("/hello", (req, res) -> {
        	JSONObject body = new JSONObject(req.body());
        	return "Hello " + body.getString("name");
        });
    }
}
It is surprising that this amount of Java code can run a web server as I have not caught up with latest server side technology in Java. I do not even know which line of the above code starts the server that listens on a TCP port. Spark can make servlet a thing of the past.

However, I could not find these libraries while I was looking for a solution. Also, a Java project normally requires a build system like maven or gradle that forces me to write a verbose XML. In fact, I had trouble figuring our all the chores around gradle and Eclipse while trying to compile and run the above simple code. (This is the first time I used gradle.)

JavaScript
I have used this language for a few projects that ran entirely within web browsers, but I do not have real experience building a server app using JavaScript. I have found this framework called Express based on Node.js. Below is a working code based on the examples in the Express site:
const express = require('express')
const bodyParser = require('body-parser');
const app = express()
const port = 3000

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/hello', (req, res) => res.send('Hello ' + req.body.name))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
Clean but some unfamiliar syntax. As for JOSN handling, the body-parser will convert JSON in a POST body into native data structure in the 'req' object. Accessing properties is very easy.

Perl
I have been a reluctant user of this language from the beginning due to its excessive use of signs or special characters like $ % @ _ => -> ... I still think that these signs decrease readability and writeability of code. I occasionally use it for ad-hoc, small tasks, but not for this one.

Anyway, here is what I found: Mojolicious. JSON handling is already part of the library and data can be accessed very easily:
use Mojolicious::Lite;

post '/hello' => sub {
    my $c = shift;
    my $hash = $c->req->json;
    $c->render(text => 'Hello ' . $hash->{name}, format=>'txt');
};

app->start;
This is as intriguing as Spark, except, I still do not like the way $ is used in this language. I thought hash prefix is %. What is that $ in front of hash?

Python
I had not used Python much for serious projects. However, I realized that it could convert JSON data to and from native representation very easily. Syntax appeared familiar to me as it is closer to C++ and Java-style object-based programming than JavaScript or Ruby. Also there are HTTP/REST frameworks like Flask. Threading is there, too, and data structures that I would use internally were thread-safe. It appeared promising for what I was trying to achieve. Below is a working example:
from flask import Flask, request
app = Flask(__name__)

@app.route('/hello', methods=['POST'])
def hello():
    data = request.get_json()
    return "Hello " + data['name']

app.run(host='0.0.0.0', port=5000, debug=True)
Quite simple and the @ decorator is already familiar to me through Java annotations.

Flask already provides an API for accessing JSON data in a request coming from a client. 'request' is an object that is accessible from a Flask application, and the object has a method 'get_json()'. Then properties in a json object can be accessed in a straight forward way.

Ruby
I was once assigned a project that manipulated Excel spreadsheets by Ruby code. It was ok for that particular task, but I did not like the use of signs in this language either. A REST framework that I have found is Sinatra. I have arranged the example codes in their web pages as below:
require 'sinatra'

post '/hello' do
  request.body.rewind  # in case someone already read it
  data = JSON.parse request.body.read
  "Hello #{data['name']}!"
end
Looks clean, and it works. This is not as bad as I had imagined. It also shows how posted JSON can be handled.

Conclusion
I do not see a clear winner in this comparison. It is a matter of preference. Of course, above examples are only scratching the surface, and you will face idiosyncrasies in each language as you start utilizing more features.

I chose Python this time due to its syntax and because it does not require a build system like maven or gradle up-front.

On the other hand, to me, clear loser appears to be C++. (To be fair, I used to write tons of C++ codes at work!) I have been poking around for C++ libraries for this particular task, but without success. I want to hear from experts how simple it can get in C++ with Boost or some other libraries.
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。