func (s *Solid) MoveToPositive() {
	measure := s.Measure()
	var translationVector Vec3
	for dim := 0; dim < 3; dim++ {
		if measure.Min[dim] < 0 {
			translationVector[dim] = -measure.Min[dim]  
		}
	}
	if translationVector != vec3Zero {
		s.Translate(translationVector)
	}
}
MoveToPositive moves the solid into the positive octant if necessary, as prescribed by
the original STL format spec. Some applications tolerate negative coordinates. This also
makes sense, as the origin is a perfect reference point for rotations.
package stl
type Solid struct {
	BinaryHeader []byte
	Name string
	Triangles []Triangle
	IsAscii bool
}
func (s *Solid) SetName(name string) {
	s.Name = name
}
func (s *Solid) SetBinaryHeader(header []byte) {
	s.BinaryHeader = header
}
func (s *Solid) SetASCII(isASCII bool) {
	s.IsAscii = isASCII
}
func (s *Solid) SetTriangleCount(n uint32) {
	l := uint32(len(s.Triangles))
	c := uint32(cap(s.Triangles))
	if n < l {
		s.Triangles = s.Triangles[:n]
		return
	}
	if n <= c {
		return
	}
	oldTriangles := s.Triangles
	s.Triangles = make([]Triangle, l, n)
	if l > 0 {
		copy(s.Triangles[:l], oldTriangles)
	}
}
func (s *Solid) AppendTriangle(t Triangle) {
	s.Triangles = append(s.Triangles, t)
}
type SolidMeasure struct {
	Min Vec3
	Max Vec3
	Len Vec3
}
func (s *Solid) Measure() SolidMeasure {
	var measure SolidMeasure
	if len(s.Triangles) == 0 {
		return measure
	}
	a := &s.Triangles[0].Vertices[0]
	measure.Min = *a
	measure.Max = *a
	for _, triangle := range s.Triangles {
		for d := 0; d < 3; d++ {
			measure.Min[d] = min4(measure.Min[d], triangle.Vertices[0][d], triangle.Vertices[1][d], triangle.Vertices[2][d])
			measure.Max[d] = max4(measure.Max[d], triangle.Vertices[0][d], triangle.Vertices[1][d], triangle.Vertices[2][d])
		}
	}
	measure.Len = measure.Max.diff(measure.Min)
	return measure
}
func (s *Solid) Transform(transformationMatrix *Mat4) {
	l := len(s.Triangles)
	for i := 0; i < l; i++ {
		s.Triangles[i].transform(transformationMatrix)
	}
}
func (s *Solid) TransformNR(transformationMatrix *Mat4) {
	l := len(s.Triangles)
	for i := 0; i < l; i++ {
		s.Triangles[i].transformNR(transformationMatrix)
	}
}
func (s *Solid) RecalculateNormals() {
	for i := 0; i < len(s.Triangles); i++ {
		s.Triangles[i].recalculateNormal()
	}
}
func (s *Solid) Scale(factor float64) {
	for i := 0; i < len(s.Triangles); i++ {
		t := &s.Triangles[i]
		for v := 0; v < 3; v++ {
			for d := 0; d < 3; d++ {
				t.Vertices[v][d] = float32(factor * float64(t.Vertices[v][d]))
			}
		}
	}
}
func (s *Solid) Stretch(vec Vec3) {
	for i := 0; i < len(s.Triangles); i++ {
		t := &s.Triangles[i]
		for v := 0; v < 3; v++ {
			for d := 0; d < 3; d++ {
				t.Vertices[v][d] = float32(float64(vec[d]) * float64(t.Vertices[v][d]))
			}
		}
		t.recalculateNormal()
	}
}
func (s *Solid) ScaleLinearDowntoSizeBox(sizeBox Vec3) {
	if sizeBox[0] <= 0 || sizeBox[1] <= 0 || sizeBox[2] <= 0 {
		panic("Not all values in sizeBox are > 0!")
	}
	measure := s.Measure()
	factor := float64(1)
	for d := 0; d < 3; d++ {
		if measure.Len[d] > sizeBox[d] {
			scale := float64(sizeBox[d]) / float64(measure.Len[d])
			if scale < factor {
				factor = scale
			}
		}
	}
	if factor != float64(1) {
		s.Scale(factor)
	}
}
func (s *Solid) Translate(vec Vec3) {
	for i := 0; i < len(s.Triangles); i++ {
		t := &s.Triangles[i]
		for v := 0; v < 3; v++ {
			for d := 0; d < 3; d++ {
				t.Vertices[v][d] += vec[d]
			}
		}
	}
}
func (s *Solid) IsInPositive() bool {
	measure := s.Measure()
	for dim := 0; dim < 3; dim++ {
		if measure.Min[dim] < 0 {
			return false
		}
	}
	return true
}