nmg_info.c File Reference

#include "common.h"
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <strings.h>
#include <math.h>
#include "machine.h"
#include "vmath.h"
#include "nmg.h"
#include "raytrace.h"

Include dependency graph for nmg_info.c:

Go to the source code of this file.

Data Structures

struct  fen2d_state
struct  vf_state
struct  edge_line_state
struct  e_and_v_state

Functions

modelnmg_find_model (const long int *magic_p_arg)
void nmg_model_bb (fastf_t *min_pt, fastf_t *max_pt, const struct model *m)
int nmg_shell_is_empty (register const struct shell *s)
shellnmg_find_s_of_lu (const struct loopuse *lu)
shellnmg_find_s_of_eu (const struct edgeuse *eu)
shellnmg_find_s_of_vu (const struct vertexuse *vu)
faceusenmg_find_fu_of_eu (const struct edgeuse *eu)
faceusenmg_find_fu_of_lu (const struct loopuse *lu)
faceusenmg_find_fu_of_vu (const struct vertexuse *vu)
faceusenmg_find_fu_with_fg_in_s (const struct shell *s1, const struct faceuse *fu2)
double nmg_measure_fu_angle (const struct edgeuse *eu, const fastf_t *xvec, const fastf_t *yvec, const fastf_t *zvec)
loopusenmg_find_lu_of_vu (const struct vertexuse *vu)
int nmg_loop_is_a_crack (const struct loopuse *lu)
int nmg_loop_is_ccw (const struct loopuse *lu, const fastf_t *norm, const struct bn_tol *tol)
const struct vertexusenmg_loop_touches_self (const struct loopuse *lu)
edgeusenmg_find_matching_eu_in_s (const struct edgeuse *eu1, const struct shell *s2)
edgeusenmg_findeu (const struct vertex *v1, const struct vertex *v2, const struct shell *s, const struct edgeuse *eup, int dangling_only)
edgeusenmg_find_eu_in_face (const struct vertex *v1, const struct vertex *v2, const struct faceuse *fu, const struct edgeuse *eup, int dangling_only)
edgeusenmg_find_e (const struct vertex *v1, const struct vertex *v2, const struct shell *s, const struct edge *ep)
edgeusenmg_find_eu_of_vu (const struct vertexuse *vu)
edgeusenmg_find_eu_with_vu_in_lu (const struct loopuse *lu, const struct vertexuse *vu)
const struct edgeusenmg_faceradial (const struct edgeuse *eu)
const struct edgeusenmg_radial_face_edge_in_shell (const struct edgeuse *eu)
const struct edgeusenmg_find_edge_between_2fu (const struct faceuse *fu1, const struct faceuse *fu2, const struct bn_tol *tol)
edgenmg_find_e_nearest_pt2 (long int *magic_p, const fastf_t *pt2, const fastf_t *mat, const struct bn_tol *tol)
void nmg_eu_2vecs_perp (fastf_t *xvec, fastf_t *yvec, fastf_t *zvec, const struct edgeuse *eu, const struct bn_tol *tol)
int nmg_find_eu_leftvec (fastf_t *left, const struct edgeuse *eu)
int nmg_find_eu_left_non_unit (fastf_t *left, const struct edgeuse *eu)
edgeusenmg_find_ot_same_eu_of_e (const struct edge *e)
vertexusenmg_find_v_in_face (const struct vertex *v, const struct faceuse *fu)
vertexusenmg_find_v_in_shell (const struct vertex *v, const struct shell *s, int edges_only)
vertexusenmg_find_pt_in_lu (const struct loopuse *lu, const fastf_t *pt, const struct bn_tol *tol)
vertexusenmg_find_pt_in_face (const struct faceuse *fu, const fastf_t *pt, const struct bn_tol *tol)
vertexnmg_find_pt_in_shell (const struct shell *s, const fastf_t *pt, const struct bn_tol *tol)
vertexnmg_find_pt_in_model (const struct model *m, const fastf_t *pt, const struct bn_tol *tol)
int nmg_is_vertex_in_edgelist (register const struct vertex *v, const struct bu_list *hd)
int nmg_is_vertex_in_looplist (register const struct vertex *v, const struct bu_list *hd, int singletons)
vertexusenmg_is_vertex_in_face (const struct vertex *v, const struct face *f)
int nmg_is_vertex_a_selfloop_in_shell (const struct vertex *v, const struct shell *s)
int nmg_is_vertex_in_facelist (register const struct vertex *v, const struct bu_list *hd)
int nmg_is_edge_in_edgelist (const struct edge *e, const struct bu_list *hd)
int nmg_is_edge_in_looplist (const struct edge *e, const struct bu_list *hd)
int nmg_is_edge_in_facelist (const struct edge *e, const struct bu_list *hd)
int nmg_is_loop_in_facelist (const struct loop *l, const struct bu_list *fu_hd)
void nmg_vertex_tabulate (struct bu_ptbl *tab, const long int *magic_p)
void nmg_vertexuse_normal_tabulate (struct bu_ptbl *tab, const long int *magic_p)
void nmg_edgeuse_tabulate (struct bu_ptbl *tab, const long int *magic_p)
void nmg_edge_tabulate (struct bu_ptbl *tab, const long int *magic_p)
void nmg_edge_g_tabulate (struct bu_ptbl *tab, const long int *magic_p)
void nmg_face_tabulate (struct bu_ptbl *tab, const long int *magic_p)
void nmg_edgeuse_with_eg_tabulate (struct bu_ptbl *tab, const struct edge_g_lseg *eg)
void nmg_edgeuse_on_line_tabulate (struct bu_ptbl *tab, const long int *magic_p, const fastf_t *pt, const fastf_t *dir, const struct bn_tol *tol)
void nmg_e_and_v_tabulate (struct bu_ptbl *eutab, struct bu_ptbl *vtab, const long int *magic_p)
int nmg_2edgeuse_g_coincident (const struct edgeuse *eu1, const struct edgeuse *eu2, const struct bn_tol *tol)


Detailed Description

A companion module to nmg_mod.c which contains routines to answer questions about n-Manifold Geometry data structures. None of these routines will modify the NMG structures in any way.

Authors - Michael John Muuss Lee A. Butler

Source - The U. S. Army Research Laboratory Aberdeen Proving Ground, Maryland 21005-5068 USA

Definition in file nmg_info.c.


Function Documentation

struct model* nmg_find_model const long int *  magic_p_arg  ) 
 

N M G _ F I N D _ M O D E L

Given a pointer to the magic number in any NMG data structure, return a pointer to the model structure that contains that NMG item.

The reason for the register variable is to leave the argument variable unmodified; this may aid debugging in event of a core dump.

Definition at line 76 of file nmg_info.c.

References bu_identify_magic(), BU_LIST_FIRST, bu_log(), shell::l, bu_list::magic, vertexuse::magic_p, edgeuse::magic_p, loopuse::magic_p, face::magic_p, NMG_EDGE_MAGIC, NMG_EDGEUSE_MAGIC, NMG_FACE_MAGIC, NMG_FACEUSE_MAGIC, NMG_LOOP_MAGIC, NMG_LOOPUSE_MAGIC, NMG_MODEL_MAGIC, NMG_REGION_MAGIC, NMG_SHELL_MAGIC, NMG_VERTEX_MAGIC, NMG_VERTEXUSE_MAGIC, NULL, rt_bomb(), and top().

Here is the call graph for this function:

void nmg_model_bb fastf_t min_pt,
fastf_t max_pt,
const struct model m
 

Definition at line 130 of file nmg_info.c.

References BU_LIST_FOR, MAX_FASTF, nmgregion_a::max_pt, nmgregion_a::min_pt, NMG_CK_MODEL, NMG_CK_REGION, NMG_CK_REGION_A, model::r_hd, and nmgregion::ra_p.

int nmg_shell_is_empty register const struct shell s  ) 
 

N M G _ S H E L L _ I S _ E M P T Y

See if this is an invalid shell i.e., one that has absolutely nothing in it, not even a lone vertexuse.

Returns - 1 yes, it is completely empty 0 no, not empty

Definition at line 171 of file nmg_info.c.

References BU_LIST_NON_EMPTY, and NMG_CK_SHELL.

double nmg_measure_fu_angle const struct edgeuse eu,
const fastf_t xvec,
const fastf_t yvec,
const fastf_t zvec
 

N M G _ M E A S U R E _ F U _ A N G L E

Return the angle in radians from the interior portion of the faceuse associated with edgeuse 'eu', measured in the coordinate system defined by xvec and yvec, which are known to be perpendicular to each other, and to the edge vector.

This is done by finding the "left-ward" vector for the edge in the face, which points into the interior of the face, and measuring the angle it forms relative to xvec and yvec.

Wire edges are indicated by always returning angle of -pi. That will be the only case for negative returns.

Definition at line 375 of file nmg_info.c.

References bn_angle_measure(), bn_pi, edgeuse::magic_p, NMG_CK_EDGEUSE, nmg_find_eu_leftvec(), NMG_LOOPUSE_MAGIC, and edgeuse::up.

Here is the call graph for this function:

int nmg_loop_is_ccw const struct loopuse lu,
const fastf_t norm,
const struct bn_tol tol
 

N M G _ L O O P _ I S _ C C W

Determine if loop proceeds counterclockwise (CCW) around the provided normal vector (which may be either the face normal, or the anti-normal).

Returns - +1 Loop is CCW, should be exterior loop. -1 Loop is CW, should be interior loop. 0 Unable to tell, error.

Definition at line 530 of file nmg_info.c.

References bu_log(), DEBUG_BASIC, DEBUG_MATH, bn_tol::dist_sq, NEAR_ZERO, nmg_loop_plane_area(), nmg_pr_lu_briefly(), bn_tol::perp, RT_G_DEBUG, V3ARGS, V4ARGS, and VDOT.

Here is the call graph for this function:

struct edge* nmg_find_e_nearest_pt2 long int *  magic_p,
const fastf_t pt2,
const fastf_t mat,
const struct bn_tol tol
 

N M G _ F I N D _ E _ N E A R E S T _ P T 2

A geometric search routine to find the edge that is neaest to the given point, when all edges are projected into 2D using the matrix 'mat'. Useful for finding the edge nearest a mouse click, for example.

Definition at line 1222 of file nmg_info.c.

References BN_CK_TOL, bu_calloc(), bu_free(), fen2d_state::ep, INFINITY, fen2d_state::mat, MAT_COPY, model::maxindex, fen2d_state::mindist, NMG_CK_EDGE, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, fen2d_state::pt2, fen2d_state::tol, fen2d_state::visited, and VMOVE.

Here is the call graph for this function:

void nmg_eu_2vecs_perp fastf_t xvec,
fastf_t yvec,
fastf_t zvec,
const struct edgeuse eu,
const struct bn_tol tol
 

N M G _ E U _ 2 V E C S _ P E R P

Given an edgeuse, return two arbitrary unit-length vectors which are perpendicular to each other and to the edgeuse, such that they can be considered the +X and +Y axis, and the edgeuse is +Z. That is, X cross Y = Z.

Useful for erecting a coordinate system around an edge suitable for measuring the angles of other edges and faces with.

Definition at line 1271 of file nmg_info.c.

References BN_CK_TOL, bn_vec_perp(), vertex_g::coord, edgeuse::eumate_p, MAGNITUDE, NMG_CK_EDGEUSE, NMG_CK_VERTEX, NMG_CK_VERTEX_G, rt_bomb(), vertexuse::v_p, VCROSS, vertex::vg_p, VSCALE, VSUB2, and edgeuse::vu_p.

Here is the call graph for this function:

int nmg_find_eu_leftvec fastf_t left,
const struct edgeuse eu
 

N M G _ F I N D _ E U _ L E F T V E C

Given an edgeuse, if it is part of a faceuse, return the inward pointing "left" vector which points into the interior of this loop, and lies in the plane of the face. The left vector is unitized.

This routine depends on the vertex ordering in an OT_SAME loopuse being properly CCW for exterior loops, and CW for interior (hole) loops.

Returns - -1 if edgeuse is not part of a faceuse. 0 if left vector successfully computed into caller's array.

Definition at line 1312 of file nmg_info.c.

References BU_LIST_PNEXT_CIRC, BU_LIST_PPREV_CIRC, bu_log(), vertex_g::coord, DEBUG_MESH_EU, edgeuse::eumate_p, faceuse::f_p, loopuse::fu_p, face::g, edgeuse::l, edgeuse::lu_p, loopuse::magic_p, edgeuse::magic_p, MAGSQ, NEAR_ZERO, NMG_ARE_EUS_ADJACENT, NMG_CK_EDGEUSE, NMG_CK_FACE, NMG_CK_FACE_G_PLANE, NMG_CK_FACEUSE, NMG_CK_LOOPUSE, NMG_FACEUSE_MAGIC, NMG_GET_FU_NORMAL, NMG_LOOPUSE_MAGIC, nmg_pr_fu_briefly(), NULL, face::plane_p, rt_bomb(), loopuse::up, edgeuse::up, V3ARGS, vertexuse::v_p, VBLEND2, VCROSS, VDOT, vertex::vg_p, VMOVE, VSUB2, edgeuse::vu_p, and VUNITIZE.

Here is the call graph for this function:

int nmg_find_eu_left_non_unit fastf_t left,
const struct edgeuse eu
 

N M G _ F I N D _ E U _ L E F T _ N O N _ U N I T

Given an edgeuse, if it is part of a faceuse, return the inward pointing "left" vector which points into the interior of this loop, and lies in the plane of the face. The left vector is not unitized.

This routine depends on the vertex ordering in an OT_SAME loopuse being properly CCW for exterior loops, and CW for interior (hole) loops.

Returns - -1 if edgeuse is not part of a faceuse. 0 if left vector successfully computed into caller's array.

Definition at line 1462 of file nmg_info.c.

References vertex_g::coord, edgeuse::eumate_p, loopuse::fu_p, edgeuse::lu_p, loopuse::magic_p, edgeuse::magic_p, NMG_CK_EDGEUSE, NMG_FACEUSE_MAGIC, NMG_GET_FU_NORMAL, NMG_LOOPUSE_MAGIC, loopuse::up, edgeuse::up, vertexuse::v_p, VCROSS, vertex::vg_p, VSUB2, and edgeuse::vu_p.

struct vertexuse* nmg_find_pt_in_lu const struct loopuse lu,
const fastf_t pt,
const struct bn_tol tol
 

N M G _ F I N D _ P T _ I N _ L U

Conduct a geometric search for a vertex in loopuse 'lu' which is "identical" to the given point, within the specified tolerance. The loopuse may be part of a face, or it may be wires.

Returns - NULL No vertex matched (struct vertexuse *) A matching vertexuse from that loopuse.

Definition at line 1611 of file nmg_info.c.

References BU_LIST_FIRST, BU_LIST_FIRST_MAGIC, BU_LIST_FOR, vertex_g::coord, bn_tol::dist_sq, loopuse::down_hd, MAGSQ, NMG_CK_VERTEX, NMG_CK_VERTEX_G, NMG_EDGEUSE_MAGIC, NMG_VERTEXUSE_MAGIC, NULL, rt_bomb(), vertexuse::v_p, vertex::vg_p, VSUB2, and edgeuse::vu_p.

Here is the call graph for this function:

struct vertexuse* nmg_find_pt_in_face const struct faceuse fu,
const fastf_t pt,
const struct bn_tol tol
 

N M G _ F I N D _ P T _ I N _ F A C E

Conduct a geometric search for a vertex in face 'fu' which is "identical" to the given point, within the specified tolerance.

Returns - NULL No vertex matched (struct vertexuse *) A matching vertexuse from that face.

Definition at line 1661 of file nmg_info.c.

References BN_CK_TOL, BU_LIST_FOR, faceuse::lu_hd, NMG_CK_FACEUSE, NMG_CK_LOOPUSE, nmg_find_pt_in_lu(), and NULL.

Here is the call graph for this function:

struct vertex* nmg_find_pt_in_shell const struct shell s,
const fastf_t pt,
const struct bn_tol tol
 

N M G _ F I N D _ P T _ I N _ S H E L L

Given a point in 3-space and a shell pointer, try to find a vertex anywhere in the shell which is within sqrt(tol_sq) distance of the given point.

The algorithm is a brute force, and should be used sparingly. Mike Gigante's NUgrid technique would work well here, if searching was going to be needed for more than a few points.

Returns - pointer to vertex with matching geometry NULL

XXX Why does this return a vertex, while it's helpers return a vertexuse?

Definition at line 1695 of file nmg_info.c.

References BN_CK_TOL, BU_LIST_FIRST, BU_LIST_FOR, BU_LIST_NOT_HEAD, BU_LIST_PNEXT, BU_LIST_PNEXT_PNEXT, vertex_g::coord, bn_tol::dist_sq, shell::eu_hd, shell::fu_hd, faceuse::fumate_p, shell::lu_hd, loopuse::lumate_p, MAGSQ, NMG_CK_EDGEUSE, NMG_CK_FACEUSE, NMG_CK_LOOPUSE, NMG_CK_SHELL, NMG_CK_VERTEX, NMG_CK_VERTEX_G, NMG_CK_VERTEXUSE, nmg_find_pt_in_face(), nmg_find_pt_in_lu(), vertexuse::v_p, vertex::vg_p, VSUB2, shell::vu_p, and edgeuse::vu_p.

Here is the call graph for this function:

struct vertex* nmg_find_pt_in_model const struct model m,
const fastf_t pt,
const struct bn_tol tol
 

N M G _ F I N D _ P T _ I N _ M O D E L

Brute force search of the entire model to find a vertex that matches this point. XXX Shouldn't this return the _closest_ match, not just the XXX first match within tolerance?

Definition at line 1772 of file nmg_info.c.

References BN_CK_TOL, BU_LIST_FOR, NMG_CK_MODEL, NMG_CK_REGION, NMG_CK_SHELL, NMG_CK_VERTEX, nmg_find_pt_in_shell(), NULL, model::r_hd, and nmgregion::s_hd.

Here is the call graph for this function:

int nmg_is_vertex_in_edgelist register const struct vertex v,
const struct bu_list hd
 

N M G _ I S _ V E R T E X _ I N _ E D G E L I S T

Returns - 1 If found 0 If not found

Definition at line 1802 of file nmg_info.c.

References BU_LIST_FOR, NMG_CK_EDGEUSE, NMG_CK_VERTEX, and NMG_CK_VERTEXUSE.

int nmg_is_vertex_in_looplist register const struct vertex v,
const struct bu_list hd,
int  singletons
 

N M G _ I S _ V E R T E X _ I N _ L O O P L I S T

Returns - 1 If found 0 If not found

Definition at line 1824 of file nmg_info.c.

References BU_LIST_FIRST, BU_LIST_FIRST_MAGIC, BU_LIST_FOR, NMG_CK_LOOPUSE, NMG_CK_VERTEX, NMG_CK_VERTEXUSE, NMG_EDGEUSE_MAGIC, nmg_is_vertex_in_edgelist(), NMG_VERTEXUSE_MAGIC, rt_bomb(), and vertexuse::v_p.

Here is the call graph for this function:

int nmg_is_vertex_in_facelist register const struct vertex v,
const struct bu_list hd
 

N M G _ I S _ V E R T E X _ I N _ F A C E L I S T

Returns - 1 If found 0 If not found

Definition at line 1923 of file nmg_info.c.

References BU_LIST_FOR, NMG_CK_FACEUSE, NMG_CK_VERTEX, and nmg_is_vertex_in_looplist().

Here is the call graph for this function:

void nmg_vertex_tabulate struct bu_ptbl tab,
const long int *  magic_p
 

N M G _ V E R T E X _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which has every vertex pointer from there on "down" in the model, each one listed exactly once.

Definition at line 2072 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, vf_state::tabl, vf_state::visited, and void().

Here is the call graph for this function:

void nmg_vertexuse_normal_tabulate struct bu_ptbl tab,
const long int *  magic_p
 

N M G _ V E R T E X U S E_ N O R M A L _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which has every vertexuse normal pointer from there on "down" in the model, each one listed exactly once.

Definition at line 2127 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, vf_state::tabl, vf_state::visited, and void().

Here is the call graph for this function:

void nmg_edgeuse_tabulate struct bu_ptbl tab,
const long int *  magic_p
 

N M G _ E D G E U S E _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which has every edgeuse pointer from there on "down" in the model, each one listed exactly once.

Definition at line 2179 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, vf_state::tabl, vf_state::visited, and void().

Here is the call graph for this function:

void nmg_edge_tabulate struct bu_ptbl tab,
const long int *  magic_p
 

N M G _ E D G E _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which has every edge pointer from there on "down" in the model, each one listed exactly once.

Definition at line 2231 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, vf_state::tabl, vf_state::visited, and void().

Here is the call graph for this function:

void nmg_edge_g_tabulate struct bu_ptbl tab,
const long int *  magic_p
 

N M G _ E D G E _ G _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which has every edge pointer from there on "down" in the model, each one listed exactly once.

Definition at line 2292 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, vf_state::tabl, vf_state::visited, and void().

Here is the call graph for this function:

void nmg_face_tabulate struct bu_ptbl tab,
const long int *  magic_p
 

N M G _ F A C E _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which has every face pointer from there on "down" in the model, each one listed exactly once.

Definition at line 2344 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, vf_state::tabl, vf_state::visited, and void().

Here is the call graph for this function:

void nmg_edgeuse_on_line_tabulate struct bu_ptbl tab,
const long int *  magic_p,
const fastf_t pt,
const fastf_t dir,
const struct bn_tol tol
 

N M G _ E D G E U S E _ O N _ L I N E _ T A B U L A T E

Given a pointer to any nmg data structure, build an bu_ptbl list which cites every edgeuse pointer from there on "down" in the model that has both vertices within tolerance of the given line.

XXX This routine is a potential source of major trouble. XXX If there are "nearby" edges that "should" be on the list but XXX don't make it, then the intersection calculations might XXX miss important intersections. As an admittedly grubby workaround, use 10X the distance tol here, just to get more candidates onto the list. The caller will have to wrestle with the added fuzz.

Definition at line 2461 of file nmg_info.c.

References BN_CK_TOL, bu_calloc(), bu_free(), bu_ptbl_init(), edge_line_state::dir, bn_tol::dist, bn_tol::dist_sq, model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, edge_line_state::pt, edge_line_state::tabl, edge_line_state::tol, edge_line_state::visited, VMOVE, and void().

Here is the call graph for this function:

void nmg_e_and_v_tabulate struct bu_ptbl eutab,
struct bu_ptbl vtab,
const long int *  magic_p
 

N M G _ E _ A N D _ V _ T A B U L A T E

Build lists of all edges (represented by one edgeuse on that edge) and all vertices found underneath the NMG entity indicated by magic_p.

Definition at line 2550 of file nmg_info.c.

References bu_calloc(), bu_free(), bu_ptbl_init(), e_and_v_state::edges, model::maxindex, NMG_CK_MODEL, nmg_find_model(), nmg_visit(), NULL, e_and_v_state::verts, e_and_v_state::visited, and void().

Here is the call graph for this function:


Generated on Mon Sep 18 01:25:07 2006 for BRL-CAD by  doxygen 1.4.6