Solved

Displaying Decimal

Posted on 2013-06-06
13
325 Views
Last Modified: 2013-06-06
Hi,

How can change the following code to display 6 decimal places?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

namespace WebApplication1
{
    public class Triangle
    {
        public double x; public double y; public double z;
    }

    public class STLUtils
    {
        public enum LengthType { inch, cm } ;

        List<byte[]> _normals = new List<byte[]>();
        List<byte[]> _points = new List<byte[]>();
        List<Triangle> _triangles = new List<Triangle>();
        List<byte> _bytecount = new List<byte>();
        byte[] _fileBytes;
        LengthType _lengthType;
        string _filename;

        public bool IsValidated(string[] args)
        {
            if (args.Length != 2) return false;
            if (!Enum.TryParse<LengthType>(args[1], true, out _lengthType))
            {
                return false;
            }

            _filename = args[0];

            return File.Exists(_filename);
        }

        public double CalculateVolume()
        {
            //read binary file
            _fileBytes = File.ReadAllBytes(_filename);

            //reverse array if little indian
            if (BitConverter.IsLittleEndian)
                Array.Reverse(_fileBytes);

            //read length
            int length = ReadLength();

            double totalVol = 0;

            //skip 80(header) + 4(length)
            var bytes = _fileBytes.Skip(84);

            //loop through all triangles data
            for (int i = 0; i < length; i++)
            {
                _normals.Add(bytes.Take(12).ToArray());

                var p1 = bytes.Skip(12).Take(12).ToArray();
                var p2 = bytes.Skip(24).Take(12).ToArray();
                var p3 = bytes.Skip(36).Take(12).ToArray();
                var b = bytes.Skip(48).Take(2);

                var l = _points.Count;
                _points.Add(p1);
                _points.Add(p2);
                _points.Add(p3);
                _triangles.Add(new Triangle { x = l, y = l + 1, z = l + 2 });

                _bytecount.Add(b.First());
                totalVol += signedVolumeOfTriangle(p1, p2, p3);
                bytes = bytes.Skip(50);
            }

            //convert to required length type (cm/inch)
            return (_lengthType == LengthType.cm) ?
                totalVol / 1000 :
                cm3_To_inch3Transform(totalVol / 1000);
        }

        private double cm3_To_inch3Transform(double totalVol)
        {
            return totalVol * 0.0610237441;
        }

        private int ReadLength()
        {
            //skip 80 chars (header), read next 4 bytes to get length
            int length = BitConverter.ToInt32(_fileBytes.Skip(80).Take(4).ToArray(), 0);
            return length;
        }

        public double signedVolumeOfTriangle(byte[] p1, byte[] p2, byte[] p3)
        {
            double v321 = p3[0] * p2[1] * p1[2];
            double v231 = p2[0] * p3[1] * p1[2];
            double v312 = p3[0] * p1[1] * p2[2];
            double v132 = p1[0] * p3[1] * p2[2];
            double v213 = p2[0] * p1[1] * p3[2];
            double v123 = p1[0] * p2[1] * p3[2];
            return (1.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123);
        }
    }
}

Open in new window


thanks

ayha
0
Comment
Question by:ayha1999
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
13 Comments
 
LVL 57

Expert Comment

by:Julian Hansen
ID: 39225137
Where is it not showing 6 decimals
0
 
LVL 7

Author Comment

by:ayha1999
ID: 39225147
when I executed the code, the result should be 0.000128 but it displayed 0 instead. how can I display the result with decimals?

Thanks
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 39225169
post the whole code.
what do u pass to STLUtils as parameters?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 7

Author Comment

by:ayha1999
ID: 39225177
An stl file is passed.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;l

namespace WebApplication1
{
    public class Triangle
    {
        public double x; public double y; public double z;
    }

    public class STLUtils
    {
        public enum LengthType { inch, cm } ;

        List<byte[]> _normals = new List<byte[]>();
        List<byte[]> _points = new List<byte[]>();
        List<Triangle> _triangles = new List<Triangle>();
        List<byte> _bytecount = new List<byte>();
        byte[] _fileBytes;
        LengthType _lengthType;
        string _filename;

        public bool IsValidated(string[] args)
        {
            if (args.Length != 2) return false;
            if (!Enum.TryParse<LengthType>(args[1], true, out _lengthType))
            {
                return false;
            }

            _filename = args[0];

            return File.Exists(_filename);
        }

        public double CalculateVolume()
        {
            //read binary file
            _fileBytes = File.ReadAllBytes(_filename);

            //reverse array if little indian
            if (BitConverter.IsLittleEndian)
                Array.Reverse(_fileBytes);

            //read length
            int length = ReadLength();

            double totalVol = 0;

            //skip 80(header) + 4(length)
            var bytes = _fileBytes.Skip(84);

            //loop through all triangles data
            for (int i = 0; i < length; i++)
            {
                _normals.Add(bytes.Take(12).ToArray());

                var p1 = bytes.Skip(12).Take(12).ToArray();
                var p2 = bytes.Skip(24).Take(12).ToArray();
                var p3 = bytes.Skip(36).Take(12).ToArray();
                var b = bytes.Skip(48).Take(2);

                var l = _points.Count;
                _points.Add(p1);
                _points.Add(p2);
                _points.Add(p3);
                _triangles.Add(new Triangle { x = l, y = l + 1, z = l + 2 });

                _bytecount.Add(b.First());
                totalVol += signedVolumeOfTriangle(p1, p2, p3);
                bytes = bytes.Skip(50);
            }

            //convert to required length type (cm/inch)
            return (_lengthType == LengthType.cm) ?
                totalVol / 1000 :
                cm3_To_inch3Transform(totalVol / 1000);
        }

        private double cm3_To_inch3Transform(double totalVol)
        {
            return totalVol * 0.0610237441;
        }

        private int ReadLength()
        {
            //skip 80 chars (header), read next 4 bytes to get length
            int length = BitConverter.ToInt32(_fileBytes.Skip(80).Take(4).ToArray(), 0);
            return length;
        }

        public double signedVolumeOfTriangle(byte[] p1, byte[] p2, byte[] p3)
        {
            double v321 = p3[0] * p2[1] * p1[2];
            double v231 = p2[0] * p3[1] * p1[2];
            double v312 = p3[0] * p1[1] * p2[2];
            double v132 = p1[0] * p3[1] * p2[2];
            double v213 = p2[0] * p1[1] * p3[2];
            double v123 = p1[0] * p2[1] * p3[2];
            return (1.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123);
        }
    }
}
            STLUtils stlUtils = new STLUtils();
            if (stlUtils.IsValidated(new string[] { @"c:\gf.stl", "cm" }))
            {
                {
                    double volume = stlUtils.CalculateVolume();
                    Response.Write(volume);
                }
            }

Open in new window

0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39225209
Change line 112 to:

Response.Write(volume.ToString("0.000000"));

Open in new window

0
 
LVL 57

Expert Comment

by:Julian Hansen
ID: 39225212
can you post your stl file (gf.stl)
0
 
LVL 7

Author Comment

by:ayha1999
ID: 39225239
I cannot attache stl file but a sample is available at\


http://orion.math.iastate.edu/burkardt/data/stl/bottle.stl

thanks
0
 
LVL 57

Expert Comment

by:Julian Hansen
ID: 39225321
Are you sure that is the right file?

In your code the ReadLength method is used to get the length of the file - but this is not working on this file because the method expects the file to have a header with a length in it - which is not present.
0
 
LVL 7

Author Comment

by:ayha1999
ID: 39225365
both bottle and gf are stl files.Anyway a working sample is here. I tested and it returns 0 volume.

the actual volume is 8.09431408456 cubic cm

http://www.deskproto.com/download/3dmodels.htm
      
STL file of the Cellphone front
0
 
LVL 57

Expert Comment

by:Julian Hansen
ID: 39225391
You posted an ASCII stl file not a binary file - your application is expecting a binary file.

Also you are reversing the data when you read it in which is messing everything up. The endianess of the data in the file is on a per item basis - reversing the whole file does not achieve the same result.

You are also passing raw bytes to the signedVolumeOfTriangle function without converting.

In short the code is not right for what you want to do.
0
 
LVL 7

Author Comment

by:ayha1999
ID: 39225933
Hi julianH,

this c# code is based the following python script which accepts stl file and returns volume.

'''
VOLUME CALCULATION STL binary MODELS
Author: Mar Canet (mar.canet@gmail.com) - september 2012
Description: useful to calculate cost in a 3D printing ABS or PLA usage
'''
import struct
import sys

class STLUtils:
	def resetVariables(self):
		self.normals = []
		self.points = []
		self.triangles = []
		self.bytecount = []
		self.fb = [] # debug list

	# Calculate volume fo the 3D mesh using Tetrahedron volume
	# based in: http://stackoverflow.com/questions/1406029/how-to-calculate-the-volume-of-a-3d-mesh-object-the-surface-of-which-is-made-up
	def signedVolumeOfTriangle(self,p1, p2, p3):
		v321 = p3[0]*p2[1]*p1[2]
		v231 = p2[0]*p3[1]*p1[2]
		v312 = p3[0]*p1[1]*p2[2]
		v132 = p1[0]*p3[1]*p2[2]
		v213 = p2[0]*p1[1]*p3[2]
		v123 = p1[0]*p2[1]*p3[2]
		return (1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123)

	def unpack(self, sig, l):
		s = self.f.read(l)
		self.fb.append(s)
		return struct.unpack(sig, s)

	def read_triangle(self):
		n  = self.unpack("<3f", 12)
		p1 = self.unpack("<3f", 12)
		p2 = self.unpack("<3f", 12)
		p3 = self.unpack("<3f", 12)
		b  = self.unpack("<h", 2)

		self.normals.append(n)
		l = len(self.points)
		self.points.append(p1)
		self.points.append(p2)
		self.points.append(p3)
		self.triangles.append((l, l+1, l+2))
		self.bytecount.append(b[0])
		return self.signedVolumeOfTriangle(p1,p2,p3)

	def read_length(self):
   		length = struct.unpack("@i", self.f.read(4))
   		return length[0]

	def read_header(self):
		self.f.seek(self.f.tell()+80)

	def cm3_To_inch3Transform(self, v):
		return v*0.0610237441

	def calculateWeight(self,volumeIn_cm):
		return volumeIn_cm*1.04

	def calculateVolume(self,infilename, unit):
		print infilename
		self.resetVariables()
		totalVolume = 0
		try:
			self.f = open( infilename, "rb")
			self.read_header()
			l = self.read_length()
			print "total triangles:",l
			try:
				while True:
					totalVolume +=self.read_triangle()
			except Exception, e:
				#print e
				print "End calculate triangles volume"
			#print len(self.normals), len(self.points), len(self.triangles), l, 
			if unit=="cm":
				totalVolume = (totalVolume/1000)
				print "Total volume:", totalVolume,"cm"
			else:
				totalVolume = self.cm3_To_inch3Transform(totalVolume/1000)
				print "Total volume:", totalVolume,"inch"
		except Exception, e:
			print e
		return totalVolume

if __name__ == '__main__':
	if len(sys.argv)==1:
		print "Define model to calculate volume ej: python mesure_volume.py torus.stl"
	else:
		mySTLUtils = STLUtils()
		if(len(sys.argv)>2 and sys.argv[2]=="inch"):
			mySTLUtils.calculateVolume(sys.argv[1],"inch")
		else:
			mySTLUtils.calculateVolume(sys.argv[1],"cm")

Open in new window


Please check

thanks
0
 
LVL 57

Accepted Solution

by:
Julian Hansen earned 250 total points
ID: 39226250
Ok - but the python file makes sense - the C# code does not match what the Python file is doing.

1. You have to establish whether you are using ASCII or Binary STL files - code assumes binary but you posted an ASCII file
2. You are reversing the whole file if the system is LittleEndian based - which is going to mess up your data
3. You are passing vertices to the volume of Triangle (which is a misnomer - a triangle is typically 2d a 3d version of a triangle is a cone or a tetrahedron) in a form that they byte elements of a 32 bit number are being accesed as individual values instead of first converting the points to an Int32

That is where I stopped with the code. You posted this question as 250 points - not really an incentive to continue - I think the question has been answered if you want that code converted post another question and give it a decent point value.
0
 
LVL 7

Author Closing Comment

by:ayha1999
ID: 39226287
OK. I will open another question.

please have a look at the following question.

http://www.experts-exchange.com/Programming/Languages/Scripting/Python/Q_28149820.html

Thanks
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
parse string in c# 5 40
Using sample Autorize.net c# simple example 1 52
Read top line from CSV file 14 56
C# LINQ query question 11 29
Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question