Solved

Displaying Decimal

Posted on 2013-06-06
13
326 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
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

 
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: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

696 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