parseFace parses a face decription line: f v1[/vt1][/vn1] v2[/vt2][/vn2] v3[/vt3][/vn3] ...
(fields []string)
| 558 | // parseFace parses a face decription line: |
| 559 | // f v1[/vt1][/vn1] v2[/vt2][/vn2] v3[/vt3][/vn3] ... |
| 560 | func (dec *Decoder) parseFace(fields []string) error { |
| 561 | |
| 562 | // NOTE(quillaja): this wasn't really part of the original issue-29 |
| 563 | if dec.objCurrent == nil { |
| 564 | // if a face line is encountered before a group (g) or object (o), |
| 565 | // create a new "default" object. This 'handles' the case when |
| 566 | // a g or o line is not specified (allowed in OBJ format) |
| 567 | dec.parseObject([]string{fmt.Sprintf("unnamed%d", dec.line)}) |
| 568 | } |
| 569 | |
| 570 | // If current object has no material, appends last material if defined |
| 571 | if len(dec.objCurrent.materials) == 0 && dec.matCurrent != nil { |
| 572 | dec.objCurrent.materials = append(dec.objCurrent.materials, dec.matCurrent.Name) |
| 573 | } |
| 574 | |
| 575 | if len(fields) < 3 { |
| 576 | return dec.formatError("Face line with less 3 fields") |
| 577 | } |
| 578 | var face Face |
| 579 | face.Vertices = make([]int, len(fields)) |
| 580 | face.Uvs = make([]int, len(fields)) |
| 581 | face.Normals = make([]int, len(fields)) |
| 582 | if dec.matCurrent != nil { |
| 583 | face.Material = dec.matCurrent.Name |
| 584 | } else { |
| 585 | // TODO (quillaja): do something better than spamming warnings for each line |
| 586 | // dec.appendWarn(objType, "No material defined") |
| 587 | face.Material = "internal default" // causes error on in NewGeom() if "" |
| 588 | // dec.matCurrent = defaultMat |
| 589 | } |
| 590 | face.Smooth = dec.smoothCurrent |
| 591 | |
| 592 | for pos, f := range fields { |
| 593 | |
| 594 | // Separate the current field in its components: v vt vn |
| 595 | vfields := strings.Split(f, "/") |
| 596 | if len(vfields) < 1 { |
| 597 | return dec.formatError("Face field with no parts") |
| 598 | } |
| 599 | |
| 600 | // Get the index of this vertex position (must always exist) |
| 601 | val, err := strconv.ParseInt(vfields[0], 10, 32) |
| 602 | if err != nil { |
| 603 | return err |
| 604 | } |
| 605 | |
| 606 | // Positive index is an absolute vertex index |
| 607 | if val > 0 { |
| 608 | face.Vertices[pos] = int(val - 1) |
| 609 | // Negative vertex index is relative to the last parsed vertex |
| 610 | } else if val < 0 { |
| 611 | current := (len(dec.Vertices) / 3) - 1 |
| 612 | face.Vertices[pos] = current + int(val) + 1 |
| 613 | // Vertex index could never be 0 |
| 614 | } else { |
| 615 | return dec.formatError("Face vertex index value equal to 0") |
| 616 | } |
| 617 |
no test coverage detected